现在它在Safari和Macos上也可以在Firefox中工作!
概括
介绍
当网页无法按照某些主要浏览器或操作系统渲染或工作时,前端开发可能具有挑战性。这是您不能忽略的问题。它可能会影响许多用户,并对您的品牌产生负面影响。
在my previous post中,我展示了一个技巧,可以用纯CSS对<details>
元素进行动画,而无需任何JavaScript。但是该解决方案有两个问题:
- 它在Safari和 中不起作用
- 它在MacOS上的Firefox中不起作用。
我很高兴解决了这些问题,现在动画在Windows,Linux,Android,MacOS或iOS上的所有主要浏览器中都可以使用。
plus,最终结果比原始的结果明显更好,更简单。
在这篇文章中,我使用了与原件相同的设计来比较代码中的更改。
问题
Safari浏览器
Safari对<summary>
Elementâ和::marker
pseudo-Elementâ²的支持有限。在前者中,display: flex
不起作用,您需要使用summary::-webkit-details-marker { display: none }
来删除默认的三角图标。至于后者,该浏览器的支持仅限于颜色和字体大小,也就是说没有动画。 ð
有关::marker
的问题也适用于::before
和::after
伪元素。因此,我们看不到装饰性三角图标在野生动物园中平稳旋转,只是一个突然的旋转。 ð
更糟糕的是,由于某种原因我不知道,使用<label>
和<input type="checkbox">
的原始技巧不会改变<details>
元素的高度。然后,我不得不丢弃它并发明新的。 ð
我更大的惊喜是在Firefox中。
MacOS上的Firefox
我已经期望使用:has()
伪级的方法无法正常工作,因为Firefox仍然没有为该有用的CSS功能提供默认支持(对于Mozilla而言,这不尴尬吗?)。但是,相邻的兄弟姐妹组合器(+
)方法(在Windows和Linux上确实有效)在MACOS上也失败了。 ð°
期待:
现实:
对解决方案进行调查
我使用Linux开发,因此我需要直接在MacOS上工作以立即进行编码以进行调整。
我已经知道了,经过一些试验,我找到了一个解决方案,该解决方案由原始HTML结构的这些主要更改组成:
-
启动没有
open
属性的<details>
元素(那是技巧,但现在不是必需的)。 ð -
丢弃
<input type="checkbox">
和<label>
元素,因为<details>
本身会触发动画。 ðρ© -
将
<div>
放置在<details>
元素之外的详细内容,成为其兄弟姐妹而不是其后代(这是新技巧)。 ðÖ
html
然后
<input type="checkbox" name="detail-one" id="detail-one" />
<details open>
<summary>
<label for="detail-one">Click to open and close smoothly with pure CSS</label>
</summary>
<div class="content">...</div>
</details>
现在
<details>
<summary>
<span>Click to open and close smoothly with pure CSS</span>
</summary>
</details>
<div class="content">...</div>
我已经用<span>
替换了<label>
,但是我在CSS中保持了相同的样式,因此我可以将三角图标用作::before
pseudo-lement。
由于Safari的支持不佳,您只能将动画应用于<summary>
的某些元素或伪元素,而不是<summary>
本身。否则,我们也可以丢弃<span>
。
The CSS
<details>
然后
details {
max-width: 500px;
box-sizing: border-box;
margin-top: 5px;
background: white;
transition: max-height 400ms ease-out;
max-height: 4rem; /* Set a max-height value just enough to show the summary content */
overflow: hidden; /* Hide the rest of the content */
}
现在
details {
max-width: 500px;
overflow: hidden;
}
<summary>
然后
summary {
display: block; /* This hides the summary's ::marker pseudo-element */
}
现在
summary {
display: block; /* This hides the summary's ::marker pseudo-element */
}
summary::-webkit-details-marker {
display: none; /* This also hides the ::marker pseudo-element, but in Safari */
}
<div class="content">
然后
div.content {
padding: 0 10px;
border: 2px solid #888;
}
现在
div.content {
max-width: 500px;
box-sizing: border-box;
padding: 0 10px;
max-height: 0;
overflow: hidden;
border: 2px solid transparent;
transition: max-height 400ms ease-out, border 0ms 400ms linear;
}
Max-Height的初始值为0,当<details>
打开时会更改(请参见“过渡”部分。
过渡
然后
input:checked + details,
details:has(input:checked) {
max-height: 800px; /* Set a max-height value enough to show all the content */
}
input:checked + details label::before,
details:has(input:checked) label::before {
rotate: 90deg;
transition: rotate 200ms ease-out;
}
现在
details[open] + div.content {
max-height: 800px; /* Set a max-height value enough to show all the content */
border-color: #888;
transition: max-height 400ms ease-out, border 0ms linear;
}
details[open] span::before {
rotate: 90deg;
transition: rotate 200ms ease-out;
}
使用相邻同胞组合器(+
)的技术是唯一起作用的技术。 :has()
伪级的技术不再是一种选择。
-Final结果
Final单词
如果您尚未注意到,此解决方案实际上并没有使<details>
元素的高度动画。确实,它使用该元素的开放/封闭状态来控制相邻<div>
高度的动画,该高度容纳详细内容。
因此,原始标题如何使<details>
元素完全动画在这里不准确,因为详细的内容不再是该元素的孩子。
但是,我认为好处克服了这一细节(双关语不是打算)。用户可以无缝与设计进行交互。尽管某些浏览器受到了限制,但开发人员仍会获得一个很好而干净的代码,摆脱了工作问题。
谢谢您的阅读!
notes
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/summary#browser_compatibility
https://developer.mozilla.org/en-US/docs/Web/CSS/::marker#browser_compatibility
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/summary#default_style
https://developer.mozilla.org/en-US/docs/Web/CSS/::before#browser_compatibility