React中的CSS伪元素


76

我正在构建React组件。正如React背后的一位专家在本次精彩的演讲中所建议的那样,我已经在组件中添加了CSS内联。我一直在努力寻找一种方法来内联添加CSS伪类,就像在演示文稿中名为“ :: after”的幻灯片上一样。不幸的是,我不仅需要添加该content:"";属性,还需要添加该属性position:absolute; -webkit-filter: blur(10px) saturate(2);。幻灯片显示了如何通过添加内容{/* … */},但是如何添加其他属性?

Answers:


75

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

诀窍在于,与其::after在CSS中使用以创建一个新元素,不如通过React来创建一个新元素。如果您不想在任何地方添加此元素,请制作一个可以为您完成此操作的组件。

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


很抱歉回答我自己的问题。感谢@Vjeux的回答。真的很好!
Michael Johansen

15
但是,当React JS呈现给搜索代理时,它们将为伪内容建立索引,这是不好的。例如,如果您将标题复制到::after-element中以创建自定义阴影,仅出于样式目的,那么当Google看到它时我就不会进入DOM,但是通过这种方法,Google将会看到它。您将有两个标题。
curl_brackets 2015年

4
不幸的是,当您在react中搜索伪元素时,此消息会在顶部弹出。@vjeux可能很生气,因为说CSS很不好,而实际上没有提供一个干净/完整的替代方法来代替它的响应者。该解决方案不应该被接受,它是一种退步-顺便说一句肯定它确实工作得很好AHAH

3
我认为这不是一个适当的解决方案。我在前后使用伪元素以避免创建不必要的DOM。
micky2be's

5
这不能回答问题,创建一个新元素而不是使用伪元素是不够的解决方案
Luke Flournoy

32

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

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

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

13

内联样式不支持伪或规则(例如,@ media)。建议范围包括从JavaScript中的CSS重新实现CSS功能到CSS状态(例如:hoverviaonMouseEnter和),onMouseLeave再到使用更多元素来复制伪元素(例如:after:before仅使用外部样式表)。

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

想象一个庞大的团队,其中每个开发人员都在重新创建CSS功能,例如:hover。每个开发人员都会做不同的事情,随着团队规模的扩大,如果能够做到,那就会做到。实际上,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提取的心脏示例


8

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

用安装 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

3

取决于是否只需要对几个属性进行内联样式设置,就可以执行以下解决方案(使您不必安装特殊的程序包或创建额外的元素):

https://stackoverflow.com/a/42000085

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

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


0

这不是问题的直接答案,但这可以帮助那些在style使用Typescript创建信息时遇到麻烦的人。

我收到一条错误消息,告诉我以下错误:

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

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

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

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

这可行。


3
从字面上看,问题与TypeScript无关。
phillyslick

1
@phillyslick是的。用Typescript编写时,给定的答案引发错误。我提供了该错误的解决方案。
Stuart Aitken

您的答案是关于如何键入CSS属性(尤其是位置属性类型)以及为什么不能使用字符串的。有一些解决方案(您建议一个好的方案),但是同样,这个问题与TypeScript无关。关于JavaScript,React和CSS。没有人会认为TypeScript与这个问题或其给定的解决方案有关。
phillyslick

1
@phillyslick当然,您知道Javascript和Typescript有多少重叠吗?我(当然还有其他人)无数次地在使用React时寻找问题的解决方案,并找到了用Javascript编写的解决方案,该解决方案在Typescript中也能很好地工作。但是有时候,例如上述情况并非如此。对于我来说,添加一点细微的调整以使上述解决方案对于那些在Typescript中遇到React CSS问题的人来说都是可行的,这简直就是飞跃。老实说,我根本看不到你的大问题。
Stuart Aitken

1
我的“大问题”是,您的答案对不使用TypeScript的人没有帮助。目前,您的答案位于接受的答案之上。但是,它无法回答问题-您自己说。它回答了一些用户可能遇到的与该问题有关的问题。当有人在其管道中使用SASS时会发生什么,我们也应该回答吗?那React Native呢?有人可能认为这与TypeScript一样与React相切。明白我的意思吗?
phillyslick
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.