I have a 2x2 grid that contains three divs: #blue
(2x1), #red
(1x1) and #yellow
(1x1) (see JSFiddle). This is what the grid looks like initially:
NOTE: #red
is overlapped by #blue
and hence not visible. To make it visible, the user must click Show
. This is what the grid looks like after Show
has been clicked:
In my current setup, clicking the Show
button adds the .expanded
class to #red
, which changes the line placement of #red
from grid-column: 1/2
to grid-column: 1/span2
and makes #red
visible.
This works fine, however, I don't like the abruptness of the change and would like to give #red
the appearance of sliding out from under #blue
when Show
is clicked. The problem is that since grid-column
has a discrete animation type, it cannot be tween-transitioned in the way that a continuous property like width
can.
My attempt at a work-around:
I tried specifying a width
property for #red
. It is initially set to 100px
and transitioned to 200px
when Show
is clicked.
This almost gives me the desired result in that #red
slides smoothly when Show
is clicked but not when Hide
is clicked. My guess is that grid-column
does not wait for the transition to complete and I also don't like having to hardcode the values of width
.
I also tried using translateX
with transition but once again grid-column
is set before the transition finishes.
Is there a solution to this problem that uses pure CSS? (I don't mind using JS but it is a last resort and do not want to use anything that involves setTimeout or jQuery.)
You could add another class that could take care of the hide transition combined with an webkitTransitionEnd
event.
Also note that I added a width: 50%
rather than your fixed width.
const show = document.getElementById('show');
const hide = document.getElementById('hide');
const red = document.getElementById('red');
show.addEventListener('click', function() {
red.classList.add('expanded');
red.classList.remove('notexpanded');
});
hide.addEventListener('click', function() {
red.classList.remove('expanded');
red.classList.add('notexpanded');
red.addEventListener('webkitTransitionEnd',
function(event) {
red.classList.remove('notexpanded');
}, false);
});
#page {
display: grid;
grid-template-columns: 100px 100px;
grid-template-rows: 100px 100px;
/* grid-auto-flow: column dense; */
}
#blue {
background-color: lightblue;
grid-row: 1/span 2;
grid-column: 1/2;
z-index: 1;
}
#yellow {
background-color: yellow;
height: 100%;
}
#red {
background-color: red;
text-align: right;
grid-column: 1;
grid-row: 1;
/* z-index: -1; cant click hide */
/* float: right; */
/* transform: translateX(0);
transition: transform 2s; */
width: 50%;
transition: width 2s;
}
#red.expanded {
/* transform: translateX(100%); */
width: 100%;
grid-column: 1/span 2;
}
#red.notexpanded {
/* transform: translateX(100%); */
width: 50%;
grid-column: 1/span 2;
}
<div id='page'>
<div id='blue'>
<button type='button' id='show'>Show</button>
</div>
<div id='red'>
<button type='button' id='hide'>Hide</button>
</div>
<div id='yellow'></div>
</div>