React中的CSS伪元素

时间:2015-02-02 00:42:41

标签: javascript css reactjs pseudo-element

我正在构建React组件。我在this brilliant presentation中建议的组件中添加了CSS内联,其中一个是React背后的人。我一直在努力寻找一种方法来内联添加CSS伪类,比如标题为" :: after"在演示文稿中。不幸的是,我不仅需要添加content:"";属性,还需要添加position:absolute; -webkit-filter: blur(10px) saturate(2);。幻灯片显示了如何通过{/* … */}添加内容,但是如何添加其他属性?

7 个答案:

答案 0 :(得分:55)

来自React团队的@Vjeux回复:

普通HTML / CSS:

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

采用内联样式进行反应:

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': ...}也应该有效。

答案 1 :(得分:22)

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

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

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

答案 2 :(得分:9)

内联样式不支持伪或规则(例如@media)。建议范围包括重新实现CSS中的CSS功能,例如:hover通过onMouseEnteronMouseLeave等CSS状态,以使用更多元素来重现伪元素,如:after:before只使用外部样式表。

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

想象一个庞大的团队,其中每个开发人员都在重新创建像:hover这样的CSS功能。每个开发人员以不同方式执行,因为团队规模越来越大,如果可以完成,则会完成。事实是使用JavaScript有 n 重新实现CSS功能的方法,随着时间的推移,你可以打赌每一种方式都被实现,最终结果是意大利面条代码。

那该怎么办?使用CSS。你问过内联样式会让你觉得你很可能在CSS-in-JS阵营(我也是!)。已经发现colocating 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

拉出心脏示例

答案 3 :(得分:3)

根据是否只需要对几个属性进行内联样式设置,您可以执行以下解决方案(并避免安装特殊程序包或创建其他元素):

https://stackoverflow.com/a/42000085

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

请注意,datacustomattribute必须以data开头,并且全部使用小写字母才能满足React的要求。

答案 4 :(得分:1)

不是该问题的直接答案,但这可能会对那些使用Typescript创建style信息有困难的人有所帮助。

我遇到一个错误,告诉我以下错误:

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

该错误告诉我“属性'位置'的类型不兼容”。我不知道为什么。

我通过添加严格的Typescript声明来解决此问题,如下所示:

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

这有效。

答案 5 :(得分:1)

我不知道这是否会被认为是 hacky,但它确实有效(使用 CSS 变量):

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

然后在导入的 CSS 文件中:

background:var(--color);

答案 6 :(得分:0)

您可以使用样式化的组件。

通过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