如何在使用 create-react-app 构建的应用程序中覆盖 A-Frame CSS?

How can I override A-Frame CSS in an app built using create-react-app?

我正在构建一个包含 2D 和 3D 元素的移动应用程序。

2D 元素使用 React,我使用 create-react-app 作为 build/bundling 等等

3D元素使用A-Frame.

对于 iOS,我需要获得设备方向权限,我正在使用标准 A-Frame 组件进行此操作:https://aframe.io/docs/1.3.0/components/device-orientation-permission-ui.html

但是我想通过指定我自己的 CSS(按照该页面上的建议)来更改模式的外观。

我有一个问题只出现在我的 生产 构建中。

我已经在 App.css 中编写了我想要的 CSS 覆盖。我构建了我的生产 JS 和 CSS 文件。

它们像这样包含在 index.html 中(在 <head> 中)

<script defer="defer" src="/static/js/main.6b739253.js"></script>
<link href="/static/css/main.8198a130.css" rel="stylesheet">

但是,在初始化时,A-Frame 将自己的 CSS 文件添加到 HTML header:

的末尾
<style type="text/css" data-href="src/style/aframe.css">
...CSS here...
</style>

因为 A-Frame CSS 出现在 HTML header 的末尾,它优先于我的自定义 CSS,我最终使用模态的 A-Frame 样式,而不是我的自定义样式。

我已经想出了 a 解决方案,但我认为必须有更好的解决方案...

我的解决方案:我的 top-level React 组件顶部的以下代码明确地从 HTML 中删除了 aframe.css 样式(我还添加了 A-Frame 我 不想 想直接在我的 App.css 中覆盖的样式,在那里我可以完全控制我做什么和不包括什么)。

  useEffect(() => {
    var head = document.getElementsByTagName('HEAD')[0];

    for (var ii = 0; ii < head.children.length; ii++) {
      const child = head.children[ii];
      if (child.attributes['data-href'] && 
          child.attributes['data-href'].nodeValue === "src/style/aframe.css") {
        head.removeChild(child);
      }
    }
  }, [])

我正在寻找一个更好的解决方案,我不必在我自己的 CSS 文件中复制大块 aframe.css,我可以简单地拥有两个 CSS 文件已加载,但优先顺序不同。

理想情况下,该解决方案不需要我从 create-react-app 中弹出,到目前为止我已设法避免需要这样做。

实际上这里有一个简单的解决方案。

指定元素选择器的 CSS 说明符 + class 选择器比指定 class 选择器的说明符更具体只有.

https://www.w3schools.com/css/css_specificity.asp

所以下面的CSS...

button.a-dialog-allow-button {
  background-color: red;
}

将更具体(因此优先于)A-Frame 默认值,如下所示:

.a-dialog-allow-button {
  background-color: #00ceff;
}

同样,您可以用 div.a-modal 覆盖 .a-modal,用 div.a-dialog 覆盖 .a-dialog

需要注意的一件事(这让我在测试时感到震惊)...并非所有 A-Frame 模态都使用 a-modala-dialog classes。

还有各种其他 classes,用于特定的模式 - 例如a-enter-vr-modala-orientation-modal(用于纵向/横向,而不是设备方向许可)。

因此,如果您看到 A-Frame 模态,而您的更改似乎不起作用,可能是因为它使用的模态 class 与之前的模态不同你变了。仔细检查class个名字!