Search code examples
cssflexboxtransition

Push siblings out of view while keeping their width


When hovering a flex element i now set the flex-basis to 100%. While doing this all siblings get resized to a width of 0 (i think) and this is showing in the animation.

Is it possible (preferred with just css) to let these sibling keep their width (nr of siblings is variable so in some scenarios there will be more columns then the example below) while the element that is hovered is expanding to 100% width? So that it looks as if they where pushed out of the container instead of resized to a width of 0.

Here is how it works now: https://jsfiddle.net/luffyyyyy/y8p9g2bs/8/

.container {
    width: 100vw;
    height: 60vh;
    display: flex;
    align-items: stretch;
    overflow: hidden;
}

.day-container {
    flex: 1; 
    display: flex;
    flex-direction: column;
    transition: flex-basis 1000ms ease-in-out;
}

.day-container:hover {
    flex-basis: 100%;
}

Solution

  • This is what could achieve so far. But for this to work you must know the number of sibling elements, in your case the .day-container. So, from your jsfiddle there are total of 5 .day-container elements so the 100/5 = 20% should be the flex-bases for .day-container elements.

    now we will move all the .day-container elements before the hovered one to left by 20% when .container has hovered with the help of general sibling selector '~' . Here's the code:

    .container:hover .day-container:not(:hover) {
      margin-left: -20%;
    }
    
    .container:hover .day-container:hover ~ .day-container {
      margin-left: 0;
    }
    

    finally, change transition to all for everything to move smoothly.
    This is how the final code should look like:

    body {
      margin: 0;
      padding: 0;
    }
    
    .container {
      width: 100vw;
      height: 60vh;
      display: flex;
      align-items: stretch;
      overflow: hidden;
    }
    
    .day-container {
      flex: 1 0 20%;
      display: flex;
      flex-direction: column;
      transition: all 1000ms ease-in-out;
    }
    
    .day-container:hover {
      flex-basis: 100%;
    }
    
    .item.small {
      flex: 1;
      background-color: royalblue;
    }
    
    .item.medium {
      flex: 2;
      background-color: rebeccapurple;
    }
    .item.big {
      flex: 3;
      background-color: goldenrod;
    }
    
    .container:hover .day-container:not(:hover) {
      margin-left: -20%;
    }
    
    .container:hover .day-container:hover ~ .day-container {
      margin-left: 0;
    }