React中的CSS伪元素

wrrgggsh  于 2023-02-06  发布在  React
关注(0)|答案(8)|浏览(263)

我正在构建React组件。我已经按照React的一位开发人员在this brilliant presentation中提出的建议,在组件中内联添加了CSS。我整晚都在尝试找到一种内联添加CSS伪类的方法,就像演示文稿中标题为“::after”的幻灯片所示。不幸的是,我不仅需要添加content:"";属性,还需要添加position:absolute; -webkit-filter: blur(10px) saturate(2);。幻灯片显示了如何通过{/* … */}添加内容,但如何添加其他属性呢?

wvmv3b1j

wvmv3b1j1#

收到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>
    );
},

诀窍在于,不要在CSS中使用::after来创建新元素,而是应该通过React创建新元素。如果不想在任何地方添加该元素,那么就创建一个组件来为您做这件事。
对于像-webkit-filter这样的特殊属性,编码的方法是去掉破折号,并将下一个字母大写,这样它就变成了WebkitFilter,注意{'-webkit-filter': ...}也应该可以。

xwmevbvl

xwmevbvl2#

内联样式不能用于定位伪类或伪元素。您需要使用样式表。
如果您想动态生成CSS,那么最简单的方法是创建一个DOM元素<style>

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

xiozqbni3#

如果你只需要几个属性被内联样式化,你可以做类似于这个解决方案的事情(这样你就不必安装一个特殊的包或者创建一个额外的元素):
https://stackoverflow.com/a/42000085

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

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

iugsix8n

iugsix8n4#

内联样式不支持pseudos或at-rules(例如@media)。建议的范围从在JavaScript中为CSS状态(如:hoveronMouseEnteronMouseLeave)重新实现CSS特性,到使用更多元素重新生成伪元素(如:after:before),再到只使用外部样式表。
我个人不喜欢所有这些解决方案。通过JavaScript重新实现CSS特性不能很好地扩展--添加多余的标记也不能。
想象一个大团队,其中每个开发人员都在重新创建:hover这样的CSS特性。随着团队规模的增长,每个开发人员 * 会 * 以不同的方式去做,如果能做到,就一定会做到。事实上,JavaScript有大约 n 种方法来重新实现CSS特性,随着时间的推移,你可以打赌这些方法中的每一种都能实现,最终结果是意大利面条代码。
那么该怎么做呢?使用CSS。假设你问过内联样式,你可能会认为你是CSS-in-JS阵营的(我也是!)。我发现HTML和CSS的共置和JS和HTML的共置一样有价值,很多人只是还没有意识到这一点(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提取的心脏示例

kqqjbcuj

kqqjbcuj5#

可以使用样式化构件。
使用npm i styled-components安装

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

const ComponentWithPseudoClass = 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 (
    <ComponentWithPseudoClass>...</ComponentWithPseudoClass>
  )
}

export default YourComponent
jogvjijk

jogvjijk6#

我不知道这是否会被认为是黑客,但它肯定工作(使用CSS变量):

const passedInlineStyle = { '--color':'blue'}

然后在导入的CSS文件中:

background:var(--color);
vkc1a9a2

vkc1a9a27#

最简单的技巧是在伪元素的content属性中添加'""'而不是''

const styles = {
    container: {
        // ... Container styling

        '&::after': {
            display: 'block',
            content: '""'
        }
    }
};
n53p2ov0

n53p2ov08#

这不是问题的直接答案,但这可能会帮助那些在使用Typescript创建style信息时遇到困难的人。
我收到一个错误,告诉我以下内容不正确:

let iconStyle = {
    position: 'relative',
    maxHeight: '90px',
    top: '25%',
}

错误告诉我“属性”位置“的类型不兼容”。我不知道为什么。
我通过添加一个严格的Typescript声明修复了这个问题,如下所示:

let iconStyle: CSSProperties = {
    position: 'relative',
    maxHeight: '90px',
    top: '25%',
}

这个管用。

相关问题