选择内部 flex 元素时,文本选择背景在 Safari 中变得不可见
Posted
技术标签:
【中文标题】选择内部 flex 元素时,文本选择背景在 Safari 中变得不可见【英文标题】:Text selection background becoming invisible in Safari when selecting inside flex elements 【发布时间】:2021-08-10 17:41:55 【问题描述】:当我在Safari
中的multiple flex element items
中选择文本时,selection background
在文本的某些部分变得不可见。
下面是Firefox
和Safari
区别的截图:
这里有一个简单的代码沙箱来重现:Link
以前有人遇到过这个问题吗?
【问题讨论】:
您找到解决此问题的方法了吗?如果是这样,请提交答案以领取赏金! 【参考方案1】:这是一个记录在案的Webkit/Safari bug,影响display: flex
和display: grid
。
在撰写本文时,文本选择错误似乎会影响 flex
或 grid
容器的某些直接子代的第一个 block-level 叶后代,具体取决于某些布局属性(请参阅 Layout Fiddles 下面)。
值得注意的是,user-select
属性的任何有效值都不会对上述错误产生任何影响,也不会使用::selection
伪元素。还值得注意的是,table
/display: table
、inline-block
、float
和 columns
布局似乎不受此错误的影响,因此对于某些用例来说,这些可能是可行的替代方案。然而,由于 flex
和 grid
可以说是当今构建布局的最强大工具,这里有一些解决方法仍然可以让您使用这些实现:
方法一:空块元素
由于上述错误导致 OP 示例中第二个弹性项目的第一个块级叶不可选择,因此此解决方法只是添加一个空块元素(在本例中为 div
,但任何display
值为block
的元素将起作用)高于<p>invisible</p>
解决了问题:
<div style= display: "flex" >
<div style= marginRight: 12 >
<p>blue</p>
<p>blue</p>
</div>
<div>
<div />
<p>invisible</p>
<p>blue</p>
</div>
</div>
更新的代码沙箱显示了方法 1 的实际应用:
https://codesandbox.io/s/flamboyant-raman-6yq7m
方法二:::before
伪元素
此修复使用与第一个相同的概念,不同之处在于它使用 CSS 伪元素而不是空的 div
。为简单起见,它也将此规则应用于所有弹性项目,无论它们是否会受到影响。
.flexContainer
display: flex;
.flexItem::before
display: block;
content: "";
<div class="flexContainer">
<div class="flexItem">
<p>blue</p>
<p>blue</p>
</div>
<div class="flexItem">
<p>invisible</p>
<p>blue</p>
</div>
</div>
更新的代码沙箱显示方法 2 的实际效果:
https://codesandbox.io/s/sharp-andras-jv6x4?file=/src/styles.css
这种方法可以说更易于维护,因为您不必像第一种方法那样管理特殊情况的子元素。需要注意的是,如果您打算将其用于其他用途,您将用完您的弹性项目上的唯一 ::before
伪元素。
Safari 特定修复
适用于 Safari 的兼容性修复程序在其他浏览器中是良性的,这可能是理想的解决方案。上面提到的两种方法似乎都是这种情况(至少在撰写本文时最新的 Chrome 和 Firefox 是这样,尽管进行一轮可靠的浏览器测试总是一个好主意)。
但是,如果您想“遏制黑客”,那么您可以尝试使用设备/用户代理嗅探 javascript 库(例如,react-device-detect
,如果您使用 React)并有条件地相应地呈现解决方法。
或者,如果您最终使用方法 2,那么您可以使用 Safari-specific CSS targeting 仅在 Safari 中呈现伪元素。
布局小提琴
在下面的小提琴中,我推断了 OP 的原始示例,显示了不同的 flex 和 grid 布局如何影响哪些第一叶后代显示和不显示突出显示的文本。我添加了额外的弹性项目,并嵌套了弹性容器的每个直接子元素的第一个元素,以表明树的深度似乎无关紧要。
Layout | Fiddle |
---|---|
flex row |
Fiddle |
flex row (wrap) |
Fiddle |
flex column (wrap) |
Fiddle |
grid |
Fiddle |
【讨论】:
不幸的是,我的布局需要使用flex
@JustJake 查看我更新的答案以及仍然使用flex
的解决方法。另外,感谢找到相应 webkit 错误并将链接添加到我的答案的人。我看了但没找到。
我知道有一个空的 div 看起来很老套,但是当浏览器渲染引擎坏了怎么办?似乎你要么忍受这个问题,要么你在代码中引入了一些不理想的东西。 Safari 是 10 到 15 年前的开拓者,但老实说,它开始让人感觉像是“新的 IE”。我发誓我现在遇到的所有奇怪的浏览器兼容性错误都是因为 Safari。叹息。
使用:before
伪元素添加了另一个解决方案。
我添加了指向 webkit 错误的链接。我最终在我的布局中使用的解决方案是使整个第一项成为 ::before 伪元素,但是发现您可以添加一个空的来解决一般问题非常好,我认为这是在不破坏一般布局的情况下解决错误的最佳选择。感谢您的帮助!以上是关于选择内部 flex 元素时,文本选择背景在 Safari 中变得不可见的主要内容,如果未能解决你的问题,请参考以下文章