React 中的 CSS 伪元素

IT技术 javascript css reactjs pseudo-element
2021-01-26 14:57:20

我正在构建React组件。我在组件中添加了 CSS 内联,正如React 背后的一个人这个精彩的演示中所建议的那样我整夜都在尝试找到一种方法来添加内联 CSS 伪类,就像演示文稿中标题为“::after”的幻灯片一样。不幸的是,我不仅需要添加content:"";属性,还需要添加position:absolute; -webkit-filter: blur(10px) saturate(2);. 幻灯片显示了如何通过 来添加内容{/* … */},但您将如何添加其他属性?

6个回答

收到来自React团队的@Vjeux 的回复

普通 HTML/CSS:

<div class="something"><span>Something</span></div>
<style>
    .something::after {
    content: '';
    position: absolute;
    -webkit-filter: blur(10px) saturate(2);
}
</style>

与内联样式react:

render: function() {
    return (
        <div>
          <span>Something</span>
          <div style={{position: 'absolute', WebkitFilter: 'blur(10px) saturate(2)'}} />
        </div>
    );
},

诀窍是不要::after在 CSS 中使用来创建新元素,而是应该通过 React 创建一个新元素。如果您不想在任何地方都添加这个元素,那么制作一个为您做的组件。

对于像 这样的特殊属性-webkit-filter,对它们进行编码的方法是删除破折号 - 并将下一个字母大写。所以变成了WebkitFilter. 请注意,这样做{'-webkit-filter': ...}也应该有效。

但是,当 React JS 呈现给搜索代理时,他们会索引伪内容,这并不好。例如,如果您将标题复制到::after-element 中,以创建自定义阴影,仅出于样式目的,当 Google 看到它时,我不会在 DOM 中,但是通过这种方法,Google 会看到它......含义你会有两个标题。
2021-03-14 14:57:20
这没有回答问题,创建一个新元素而不是使用伪元素不是一个充分的解决方案
2021-04-06 14:57:20
太糟糕了,当您在 react 中搜索伪元素时,它会在顶部弹出。@vjeux 可能会很恼火地说 css 很糟糕,而实际上没有为其 react-followers 提供干净/完整的替代方案。这个解决方案不应该被接受,这是一种倒退——顺便说一句,它确实工作得很好啊哈
2021-04-09 14:57:20
在我看来,这不是一个正确的解决方案。我使用之前和之后的伪元素来避免创建不必要的 DOM。
2021-04-09 14:57:20
必须抱歉回答我自己的问题。并感谢@Vjeux 的回答。它工作得很好!
2021-04-11 14:57:20

内联样式不能用于定位伪类或伪元素。您需要使用样式表。

如果要动态生成 CSS,那么最简单的方法就是创建 DOM 元素<style>

<style dangerouslySetInnerHTML={{
  __html: [
     '.my-special-div:after {',
     '  content: "Hello";',
     '  position: absolute',
     '}'
    ].join('\n')
  }}>
</style>
<div className='my-special-div'></div>

内联样式不支持伪或 at 规则(例如,@media)。建议的范围从重新实现CSS特征在JavaScript为CSS状态等:hover通过onMouseEnteronMouseLeave用多种元素来再现伪元素像:after:before只是使用一个外部的样式表。

个人不喜欢所有这些解决方案。通过 JavaScript 重新实现 CSS 功能不能很好地扩展——添加多余的标记也不能。

想象一个大型团队,其中每个开发人员都在重新创建 CSS 功能,例如:hover. 每个开发人员都会以不同的方式做这件事,随着团队规模的扩大,如果可以完成,就会完成。事实上,在 JavaScript 中,大约有n种方法可以重新实现 CSS 功能,随着时间的推移,您可以打赌实现这些方法中的每一种,最终结果都是意大利面条式代码。

那么该怎么办?使用 CSS。假设您询问了内联样式,假设您可能属于 CSS-in-JS 阵营(我也是!)。发现将 HTML 和 CSS 并置与 JS 和 HTML 并置一样有value,只是很多人还没有意识到(JS-HTML 共置一开始也有很多阻力)。

在这个空间中提出了一个名为Style It的解决方案,可以让您在 React 组件中编写纯文本 CSS。无需浪费在 JS 中重新发明 CSS 的周期。适合正确工作的正确工具,这是一个使用示例:after

npm install style-it --save

函数式语法( JSFIDDLE )

import React from 'react';
import Style from 'style-it';

class Intro extends React.Component {
  render() {
    return Style.it(`
      #heart {
        position: relative;
        width: 100px;
        height: 90px;
      }
      #heart:before,
      #heart:after {
        position: absolute;
        content: "";
        left: 50px;
        top: 0;
        width: 50px;
        height: 80px;
        background: red;
        -moz-border-radius: 50px 50px 0 0;
        border-radius: 50px 50px 0 0;
        -webkit-transform: rotate(-45deg);
        -moz-transform: rotate(-45deg);
        -ms-transform: rotate(-45deg);
        -o-transform: rotate(-45deg);
        transform: rotate(-45deg);
        -webkit-transform-origin: 0 100%;
        -moz-transform-origin: 0 100%;
        -ms-transform-origin: 0 100%;
        -o-transform-origin: 0 100%;
        transform-origin: 0 100%;
      }
      #heart:after {
        left: 0;
        -webkit-transform: rotate(45deg);
        -moz-transform: rotate(45deg);
        -ms-transform: rotate(45deg);
        -o-transform: rotate(45deg);
        transform: rotate(45deg);
        -webkit-transform-origin: 100% 100%;
        -moz-transform-origin: 100% 100%;
        -ms-transform-origin: 100% 100%;
        -o-transform-origin: 100% 100%;
        transform-origin :100% 100%;
      }
    `,
      <div id="heart" />
    );
  }
}

export default Intro;

JSX 语法( JSFIDDLE )

import React from 'react';
import Style from 'style-it';

class Intro extends React.Component {
  render() {
    return (
      <Style>
      {`
        #heart {
          position: relative;
          width: 100px;
          height: 90px;
        }
        #heart:before,
        #heart:after {
          position: absolute;
          content: "";
          left: 50px;
          top: 0;
          width: 50px;
          height: 80px;
          background: red;
          -moz-border-radius: 50px 50px 0 0;
          border-radius: 50px 50px 0 0;
          -webkit-transform: rotate(-45deg);
          -moz-transform: rotate(-45deg);
          -ms-transform: rotate(-45deg);
          -o-transform: rotate(-45deg);
          transform: rotate(-45deg);
          -webkit-transform-origin: 0 100%;
          -moz-transform-origin: 0 100%;
          -ms-transform-origin: 0 100%;
          -o-transform-origin: 0 100%;
          transform-origin: 0 100%;
        }
        #heart:after {
          left: 0;
          -webkit-transform: rotate(45deg);
          -moz-transform: rotate(45deg);
          -ms-transform: rotate(45deg);
          -o-transform: rotate(45deg);
          transform: rotate(45deg);
          -webkit-transform-origin: 100% 100%;
          -moz-transform-origin: 100% 100%;
          -ms-transform-origin: 100% 100%;
          -o-transform-origin: 100% 100%;
          transform-origin :100% 100%;
        }
     `}

      <div id="heart" />
    </Style>
  }
}

export default Intro;

CSS-Tricks 中提取的心脏示例

根据您是否只需要将几个属性设置为内联样式,您可以执行类似此解决方案的操作(并且无需安装特殊包或创建额外元素):

https://stackoverflow.com/a/42000085

<span class="something" datacustomattribute="👋">
  Hello
</span>
.something::before {
  content: attr(datascustomattribute);
  position: absolute;
}

请注意,datacustomattribute必须以data小写开头才能满足 React。

另请注意,虽然它必须是小写的,但它也可以包含破折号,例如data-custom-attribute也可以使用
2021-03-20 14:57:20
截至 2021 年 7 月,如MDN 文档中所述: attr() 函数可用于任何 CSS 属性,但对内容以外的属性的支持是实验性的,并且对 type-or-unit 参数的支持很少。
2021-04-11 14:57:20

您可以使用样式化组件。

安装它 npm i styled-components

import React from 'react';
import styled from 'styled-components';

const YourEffect = styled.div`
  height: 50px;
  position: relative;
  &:after {
    // whatever you want with normal CSS syntax. Here, a custom orange line as example
    content: '';
    width: 60px;
    height: 4px;
    background: orange
    position: absolute;
    bottom: 0;
    left: 0;
  },

const YourComponent = props => {
  return (
    <YourEffect>...</YourEffect>
  )
}

export default YourComponent