Safari 中的 Flex 过渡

Posted

技术标签:

【中文标题】Safari 中的 Flex 过渡【英文标题】:Flex transition in Safari 【发布时间】:2022-01-07 23:56:54 【问题描述】:

以下是my small contribution 中关于自动高度转换的帖子的一部分:

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>

它适用于除 Safari 之外的所有主要浏览器。是否有任何 CSS 调整以使其在 Safari 中也能顺利运行?

【问题讨论】:

【参考方案1】:

在您的代码中,flex:1 扩展为 flex: 1 1 0%,感谢您的更正。您的 the demo 确实使 flex-grow 具有动画效果,但它可以工作,因为有可用空间供内容增长。制作 flexbox flex-flow: column 并移除固定高度 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>

现在它没有动画,因为flex-grow 用于分配可用空间。如果没有可用空间,则更改 flex-grow 不会影响任何内容。


由于显示网格、百分比 flex-basisflex-grow

<!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>
这里flex-grow:0.25 不应该减小内容大小。 ref。不知何故,这发生在 Chrome 而不是 Safari 上。如果您删除display:grid,则overflow:hidden 将停止剪辑内容。我不认为 chrome 在这里是正确的,因为 flex-grow 不应该减少 .content 的大小。 我发现 Chrome 和 safari 在制作动画时如何切换属性单元存在一些差异。在 chrome 和 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>
观察者flex-basis 看看它如何在动画开始时在 chrome 上立即从 0px 切换到 0%。但在 Safari 上,它会在动画结束时切换。我不知道它与这个问题有什么关系。

解决方案:我仍然坚持动画flax-basis 而不是flex-grow 这里。如果fit-content 是实验性的并且不需要,那么您仍然可以使用min-content 和max-content。与 fit-content 不同,所有浏览器都支持它们。

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>

我们必须将 max-height 设置为固有大小以限制高度,否则它会一直增长到视口结束。 注意:我已经在 iPadOS 15.1 上的 Safari 14.1 和 Chrome 95 上测试了代码 要创建特定于 Safari 的 CSS,我参考了 https://www.browserstack.com/guide/create-browser-specific-css

【讨论】:

"在 Safari 上 flex-grow 无法设置动画。" 请参阅 this demo。 “在您的代码中,flex: 1 扩展为 flex: 1 1 0”实际上它扩展为 flex: 1 1 0%,令人惊讶的是它们是不同的。 “你没有改变 flex-basis” 我将 flex-basis: 0 更改为 flex-basis: 0%flex-grow: 0 更改为 flex-grow: 1。这就是您的演示在非 Safari 浏览器中的工作方式。 “我们必须设置max-height: fit-content来限制高度”我们最好远离实验性功能。 转换到flex-basis: 100vh 会导致与max-height 相同的问题。请参阅this post 及其 cmets。 @Mori 您的 OP 中的 sn-p 由于已知错误而工作。 bugs.chromium.org/p/chromium/issues/detail?id=1279171 Devs 不会修复它。并建议使用flex-basis: autoheight: fit-content; display: grid改为display: flex,在非Safari浏览器中仍然有效。 我认为,如果您阅读说明,这适用于提到第二次布局传递的容器。并且可能不仅仅特定于网格。【参考方案2】:

如您所知,自 Safari 13.1 (Mac) 起,flex 过渡不再有效。但是如果你使用下面的代码,它可能会起作用。

html 
  display: grid;


body 
  display: flex;
  flex-direction: column;


.content 
  background: aqua;
  height: 0;
  overflow: hidden;
  transition: all 1000ms ease;


span:hover + .content 
  height: 100%;
<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>

在上面的sn-p代码中,我把transition: all 1s easy;改成了transition: all 1000ms easy;

我是根据This和this得出这个结论的

【讨论】:

【参考方案3】:

在 safari 中的过渡有一些问题,这里讨论过: css transitions not working in safari

它不适用于auto 值和all 不能使用。 -webkit- 在开始时也应该使用。 这是我解决这个问题的技巧(已知问题:最大高度限制为 1000px):

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


span:hover + .content 
  flex: 1;
  max-height: 1000px;

【讨论】:

以上是关于Safari 中的 Flex 过渡的主要内容,如果未能解决你的问题,请参考以下文章

在 flexbox 中过渡 flex-grow 项目

忽略溢出的 CSS 不透明度过渡:隐藏在 Chrome/Safari 中

iPhone 上 iOS Safari 中的过渡会导致意外行为

当触发 iOS Safari 中的虚拟键盘时,它会使我的 CSS 过渡闪烁。如何解决这个问题?

CSS 过渡:不透明度和可见性过渡不适用于 Firefox(适用于 Chrome / Safari)

组合大小和翻译过渡会导致 Safari 卡顿