Open MayOMengxuhui opened 6 years ago
使用React的过程中,组件通过 JS 来定义 css 样式,就必须在 React 组件里面通过style属性来写。
export class App extends React.Component { render() { return( <div style={{marginTop: '10px'}}> ...... </div> ); } }
缺点:
(1)样式属性与原生 css 的写法不一致,样式名称必须用驼峰的命名方式来命令,而不是多个单词用-号分隔;单位的写法也不一致,百分比是用字符串形式。 (2)无法写伪元素,要实现hover的话就必须使用onMouseOver事件来实现,而且要写很多 JS 代码,像before和after这类伪元素则根本没法通过这种方式实现。
为了顺应组件化的潮流,人们开始考虑使用JS上编写CSS,styled components就是其中一种解决方案。styled components是一个React第三方库,作用是可以将样式写成组件的形式,实现在JS上编写CSS
使用styled-components不需要再使用className属性来控制样式,而是将样式写成更具语义化的组件的形式,如下例:
import React from 'react'; import styled from 'styled-components'; const Title = styled.h1` font-size: 1.5em; text-align: center; color: red; `; class App extends React.Component { render() { return ( <Title>Hello styled--components</Title> ) } } ReactDOM.render( <App />, document.getElementById('app') );
示例: 上例中的styled.h1是一个标签模板函数,紧跟其后的是一个模板字符串参数,“标签模板”和“模板字符串”都是es6的语法。styled.h1函数返回一个React Component,styled components会为这个React Component添加一个class,该class的值为一个随机字符串。传给styled.h1的模板字符串参数的值实际上是CSS语法,这些CSS会附加到该React Component的class中,从而为React Component添加样式。
随机字符串
在React中是通过控制className和style来控制样式的,如下例,App组件需要判断是否有primary属性来判断是否渲染”title-primary”类的样式:
export class App extends React.Component { render() { let className = this.props.primary ? "title-primary" : ''; return( <div className={className}> ... </div> ); } }
styled components使用props来控制样式,将控制样式代码放在样式组件中,使React组件更加简洁:
const Title = styled.div` font-size: 1.5em; text-align: center; color: ${props => props.primary ? 'blue' : ' red'}; ` export class App extends React.Component { render() { return ( <Title primary> Hello Styled-Component </Title> ) } }
styled components的写法中样式组件暴露props让外层JS来控制样式,不再需要className或style这样的“中间人”,移除了样式和组件间的映射关系。
CSS有一个痛点——CSS的作用域是全局的。当两个CSS选择器有冲突时,会根据选择器的权值确定使用哪一个选择选择器。当项目较大时,编写的css选择器很难判断会不会把另外一个选择器冲掉。 解决CSS作用域的其中一个方法就是使用后代选择器,这种用法和命名空间相似,即在每个选择器前添加一个父元素的选择器,从而减少选择器冲突的概率。 使用styled components会给生成的React组件添加一个值为随机字符串的className。使用同一个styled components生成的多个React组件的className是不同的,这种随机className的机制使得组件之间的className值不会冲突,从而解决了CSS全局作用域的问题。
styled components也支持css的嵌套语法:
const Title = styled.div` font-size: 1.5em; text-align: center; .content1 { color: #f16da7; margin: 10px; } .content2 { color: #98a514; } `;
export class App extends React.Component { render() { return (
) }
}
示例 ![1522584049702](https://user-images.githubusercontent.com/32735787/38172912-6bc92bd4-35e7-11e8-9d08-95169d83e272.jpg) ### 组件样式继承 - 通常在 css 中一般会通过给 class 传入多个 name 通过空格分隔的方式来复用 class 定义,类似 class="button tomato"。在 styled-components 中利用了 js 的继承实现了这种样式的复用:
const Button = styled.button color: palevioletred; font-size: 1em; margin: 1em; padding: 0.25em 1em; border: 2px solid palevioletred; border-radius: 3px; ;
color: palevioletred; font-size: 1em; margin: 1em; padding: 0.25em 1em; border: 2px solid palevioletred; border-radius: 3px;
const TomatoButton = Button.extend color: tomato; border-color: tomato; ;
color: tomato; border-color: tomato;
这篇文章有点老了,现在已经不使用 .extend 这个方法了。
styled-components
背景
使用React的过程中,组件通过 JS 来定义 css 样式,就必须在 React 组件里面通过style属性来写。
缺点:
(1)样式属性与原生 css 的写法不一致,样式名称必须用驼峰的命名方式来命令,而不是多个单词用-号分隔;单位的写法也不一致,百分比是用字符串形式。 (2)无法写伪元素,要实现hover的话就必须使用onMouseOver事件来实现,而且要写很多 JS 代码,像before和after这类伪元素则根本没法通过这种方式实现。
为了顺应组件化的潮流,人们开始考虑使用JS上编写CSS,styled components就是其中一种解决方案。styled components是一个React第三方库,作用是可以将样式写成组件的形式,实现在JS上编写CSS
基本用法
使用styled-components不需要再使用className属性来控制样式,而是将样式写成更具语义化的组件的形式,如下例:
示例: 上例中的styled.h1是一个标签模板函数,紧跟其后的是一个模板字符串参数,“标签模板”和“模板字符串”都是es6的语法。styled.h1函数返回一个React Component,styled components会为这个React Component添加一个class,该class的值为一个
随机字符串
。传给styled.h1的模板字符串参数的值实际上是CSS语法,这些CSS会附加到该React Component的class中,从而为React Component添加样式。props参数控制样式
在React中是通过控制className和style来控制样式的,如下例,App组件需要判断是否有primary属性来判断是否渲染”title-primary”类的样式:
styled components使用props来控制样式,将控制样式代码放在样式组件中,使React组件更加简洁:
styled components的写法中样式组件暴露props让外层JS来控制样式,不再需要className或style这样的“中间人”,移除了样式和组件间的映射关系。
CSS作用域
CSS有一个痛点——CSS的作用域是全局的。当两个CSS选择器有冲突时,会根据选择器的权值确定使用哪一个选择选择器。当项目较大时,编写的css选择器很难判断会不会把另外一个选择器冲掉。 解决CSS作用域的其中一个方法就是使用后代选择器,这种用法和命名空间相似,即在每个选择器前添加一个父元素的选择器,从而减少选择器冲突的概率。 使用styled components会给生成的React组件添加一个值为随机字符串的className。使用同一个styled components生成的多个React组件的className是不同的,这种随机className的机制使得组件之间的className值不会冲突,从而解决了CSS全局作用域的问题。
styled components也支持css的嵌套语法:
export class App extends React.Component { render() { return (
}
const Button = styled.button
color: palevioletred; font-size: 1em; margin: 1em; padding: 0.25em 1em; border: 2px solid palevioletred; border-radius: 3px;
;const TomatoButton = Button.extend
color: tomato; border-color: tomato;
;export class App extends React.Component { render() { return (