Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flex transition in Safari

The following is part of my small contribution to a post on auto height transitions:

html {
  display: grid;
}

body {
  display: flex;
  flex-direction: column;
}

.content {
  background: aqua;
  flex-basis: 0;
  overflow: hidden;
  transition: all 1s ease;
}

span:hover + .content {
  flex: 1;
}
<span>Hover over me!</span>

<div class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>

<p>Rest of the page content...</p>

It works in all major browsers except Safari. Any CSS tweak to run it smoothly in Safari as well?

like image 598
Mori Avatar asked Dec 01 '21 11:12

Mori


People also ask

Does Flexbox work in Safari?

Safari 14.1 now supports the gap property inside Flexbox containers, along with row-gap and column-gap . Gaps in Flexbox make it possible for web developers to create space between Flex items without resorting to annoying margin hacks.

Does display flex work on all browsers?

For simple Flexbox uses however, you can get things working well a wide range of modern browsers: Chrome, Firefox, Safari, Opera Presto 12.1+, IE 10+, iOS and Android.

Is Flex direction Animatable?

The answer is no. flex-direction is not an animatable property in CSS.

Is Flex supported by ie11?

Note also that Internet Explorer 11 supports the modern display: flex specification however it has a number of bugs in the implementation.


Video Answer


1 Answers

In your code flex:1 expands to flex: 1 1 0%, thanks for the correction.
Your the demo does animate flex-grow but it works because there is free space for the content to grow. Make the flexbox flex-flow: column and remove fixed height height: 200px;.

.flex-container {
  width: 300px;
  /* uncomment height to start animating*/
  /*height: 200px;*/
  font-size: 32px;
  outline: 1px solid black;
  display: flex;
  flex-flow: column;
}

.flex-container div {
  flex-grow: 0;
}

.item1 {
  background: #e84d51;
}

.item2 {
  background: #7ed636;
}

.item3 {
  background: #2f97ff;
}

.animated {
  animation: test 4s infinite;
}

@keyframes test {
  0% {
    flex-grow: 0;
  }
  100% {
    flex-grow: 1;
  }
}
<div class="flex-container">
  <div class="item1">1</div>
  <div class="item2 animated">2</div>
  <div class="item3">3</div>
</div>

Now it doesn't animate because flex-grow is for distributing free space. If there is no free space, then changing flex-grow doesn't affect anything.


Your code sample in the opening post works because of the weird combination of display grid, percentage flex-basis and flex-grow values < 0:

<!DOCTYPE html>
<html lang="en">
<head>
  <style>
    #grd {
      /* if you remove following line , 
      then the .content won't clip due to overflow */
      display: grid;
    }
    
    #flx {
      display: flex;
      flex-flow: column;
    }
    
    .content {
      background: aqua;
      flex-basis: 0%;
      flex-grow: 0.25;
      overflow: hidden;
    }
  </style>
</head>
<body>
  <div id=grd>
    <div id=flx>
      <span>Top</span>
      <div class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
        dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
      </div>
      <p>Bottom</p>
    </div>
  </div>
</body>
</html>

Here flex-grow:0.25 shouldn't reduce the content size. ref. Somehow this happens on Chrome and not on Safari. If you remove display:grid, then overflow:hidden stops clipping the content. I don't think chrome is correct here cos flex-grow shouldn't reduce the .content size.

There is some difference I found how Chrome and safari switch attribute units while animating. Run following code on both chrome and safari:

<!DOCTYPE html>
<html lang="en">

<head>
  <script>
    window.setInterval(function () {
      init();
    }, 400);

    function init() {
      var content = document.querySelector('.content');
      var stat = window.getComputedStyle(content).getPropertyValue('flex-basis');
      var grow = window.getComputedStyle(content).getPropertyValue('flex-grow');
      var height = window.getComputedStyle(content).getPropertyValue('height');

      document.getElementById('stat').innerText = 'flex-basis:' + stat +
        '\n' + 'flex-grow:' + grow + '\n' + 'height: ' + height;
    }
  </script>
  <style>
    #grd {
      display: grid;
    }

    #flx {
      display: flex;
      flex-flow: column;
    }

    .content {
      background: aqua;
      flex-basis: 0;
      overflow: hidden;
      transition: all 6s ease;
    }

    span:hover+.content {
      flex: 1;
    }

    p {
      white-space: pre;
    }

  </style>
</head>

<body>
  <div id=grd>
    <div id=flx>
      <span>Hover over me!</span>

      <div class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
        labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
        aliquip ex
        ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
        nulla
        pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
        laborum.</div>

      <p>Rest of the page content...</p>
      <p id="stat">stat</p>
    </div>
  </div>
</body>

</html>

Observer flex-basis see how it switches from 0px to 0% instantly on chrome on animation start. But on Safari it switches at the end of animation. I don't know how it relates to the issue.

Solution: I still stick to animating flax-basis instead of flex-grow here. If fit-content is experimental and not desired then you can still use min-content and max-content. Unlike fit-content all browsers support them.

html {
  display: grid;
}

body {
  display: flex;
  flex-direction: column;
}

.content {
  background: aqua;
  flex-basis: 0;
  overflow: hidden;
  transition: all 1s ease;

  /* limit the height */
  /* use either of these as per situation */
  max-height: fit-content;
  max-height: min-content;
  max-height: max-content;
}

span:hover+.content {
  flex: 1;
}


/* Safari 11+ */

@media not all and (min-resolution: 0.001dpcm) {
  @supports (-webkit-appearance: none) and (stroke-color: transparent) {
    span:hover + .content {
      flex-basis:100vh;
    }
  }
}


/* Safari 10.1 */

@media not all and (min-resolution: 0.001dpcm) {
  @supports (-webkit-appearance: none) and (not (stroke-color: transparent)) {
    span:hover + .content {
      flex-basis:100vh;
    }
  }
}


/* Safari 6.1-10.0 (but not 10.1) */

@media screen and (min-color-index: 0) and(-webkit-min-device-pixel-ratio:0) {
  @media {
    span:hover+.content {
      flex-basis: 100vh;
    }
  }
}
<span>Hover over me!</span>

<div class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
  in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>

<p>Rest of the page content...</p>


We have to set max-height to intrinsic size to limit the height, otherwise it'll grow till end of the view port.

Note: I've tested the code on Safari 14.1 and Chrome 95 on iPadOS 15.1
To create Safari specific CSS I've referred https://www.browserstack.com/guide/create-browser-specific-css

like image 130
the Hutt Avatar answered Oct 12 '22 23:10

the Hutt