选择内部 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 在文本的某些部分变得不可见。

下面是FirefoxSafari区别的截图:

Safari Firefox

这里有一个简单的代码沙箱来重现:Link

以前有人遇到过这个问题吗?

【问题讨论】:

您找到解决此问题的方法了吗?如果是这样,请提交答案以领取赏金! 【参考方案1】:

这是一个记录在案的Webkit/Safari bug,影响display: flexdisplay: grid

在撰写本文时,文本选择错误似乎会影响 flexgrid 容器的某些直接子代的第一个 block-level 叶后代,具体取决于某些布局属性(请参阅 Layout Fiddles 下面)。

值得注意的是,user-select 属性的任何有效值都不会对上述错误产生任何影响,也不会使用::selection 伪元素。还值得注意的是,table/display: tableinline-blockfloatcolumns 布局似乎不受此错误的影响,因此对于某些用例来说,这些可能是可行的替代方案。然而,由于 flexgrid 可以说是当今构建布局的最强大工具,这里有一些解决方法仍然可以让您使用这些实现:

方法一:空块元素

由于上述错误导致 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 中变得不可见的主要内容,如果未能解决你的问题,请参考以下文章

CSS学习总结

CSS学习总结

Flex调用Google map时,如何只显示指定区域

使用 flexbox (tailwindcss: flex-1) 如何将背景颜色添加到整个元素而不仅仅是文本?

CSS flex:行选择器中的最后一项和第一项

单独一个元素的选择器? [复制]