React 中的 CSS 伪元素
收到来自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': ...}
也应该有效。
内联样式不能用于定位伪类或伪元素。您需要使用样式表。
如果要动态生成 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
通过onMouseEnter
并onMouseLeave
用多种元素来再现伪元素像: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。
您可以使用样式化组件。
安装它 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