Reputation: 2022
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.)
Upvotes: 2
Views: 228
Reputation: 10922
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>
Upvotes: 1