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-basis
和 flex-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: auto
和height: 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 过渡的主要内容,如果未能解决你的问题,请参考以下文章
忽略溢出的 CSS 不透明度过渡:隐藏在 Chrome/Safari 中
iPhone 上 iOS Safari 中的过渡会导致意外行为
当触发 iOS Safari 中的虚拟键盘时,它会使我的 CSS 过渡闪烁。如何解决这个问题?