Css Module介紹

CSS 的規則是全局的,任何一個組件的樣式規則,都對整個頁面有效。相信寫css的人都會遇到樣式衝突(污染)的問題。css

在App.js中咱們引入子組件Child和style.csshtml

import React from 'react';
import Child from './Child';
import './style.css';

const App = () => {
  return (
    <div>
      <p className="aaa">hello</p>
      <Child />
    </div>
  )
}
    
export default App;

style.cssreact

.aaa {
    background-color: red;
}

而後Child中又引入了style1.css文件, 咱們一不當心把style1.css中的樣式又寫成了aaa,按照預期的結果App組件的p標籤背景色應該是紅色,Child組件中的p標籤背景色是藍色,那是否是這樣的呢?
child.jswebpack

import React from 'react';
import './style1.css';

const Child = () => {
  return (
    <div>
      <p className="aaa">child</p>
    </div>
  )
}
    
export default Child;

style1.cssgit

.aaa {
    background-color: blue;
}

咱們yarn start啓動項目,能夠看到頁面兩個標籤都是顯示紅色
圖片描述github

這是由於咱們在App中經過這樣的方式引入import './style.css';它的樣式做用於全局,若是咱們不注意命名的話極有可能形成樣式名重複的問題,進而形成上面樣式衝突的問題web

爲了解決全局污染的問題,那就把class命名寫長一點吧、加一層父級選擇器、下降衝突的概率,那麼CSS命名混亂了npm

CSS 模塊化的解決方案有不少,但主要有三類:編程

(1)、命名約定

規範化CSS的解決方案如:BEM、OOCSS、AMCSS、SMACSScanvas

(2)、CSS in JS

完全拋棄 CSS,用 JavaScript 寫 CSS 規則,styled-components就是其中表明。

安裝

npm install --save styled-components

通常在作項目開始時,咱們都會定義一些初始化樣式,這些樣式都是全局有效的,那麼使用這個方法該怎麼定義這些全局樣式呢?

最新版的 styled-components v4 已經將原有的injectGlobal() 方法替換成了createGlobalStyle() ,並且用法也和以前的 injectGlobal 方法不一樣了

在src下新建一個style.js(注意這裏是js後綴而不是css後綴,由於咱們要在js中寫css)

  • 一、引入新的API createGlobalStyle ,在下面建立一個 GlobalStyle 變量,用 createGlobalStyle 方法把全局樣式包裹在其中(包裹css樣式使用反引號字符串)
import { createGlobalStyle } from 'styled-components';

export const GlobalStyle = createGlobalStyle`
    html, body, div, span, applet, object, iframe,
    h1, h2, h3, h4, h5, h6, p, blockquote, pre,
    a, abbr, acronym, address, big, cite, code,
    del, dfn, em, img, ins, kbd, q, s, samp,
    small, strike, strong, sub, sup, tt, var,
    b, u, i, center,
    dl, dt, dd, ol, ul, li,
    fieldset, form, label, legend,
    table, caption, tbody, tfoot, thead, tr, th, td,
    article, aside, canvas, details, embed, 
    figure, figcaption, footer, header, hgroup, 
    menu, nav, output, ruby, section, summary,
    time, mark, audio, video {
        margin: 0;
        padding: 0;
        border: 0;
        font-size: 100%;
        font: inherit;
        vertical-align: baseline;
    }
    /* HTML5 display-role reset for older browsers */
    article, aside, details, figcaption, figure, 
    footer, header, hgroup, menu, nav, section {
        display: block;
    }
    body {
        line-height: 1;
    }
    ol, ul {
        list-style: none;
    }
    blockquote, q {
        quotes: none;
    }
    blockquote:before, blockquote:after,
    q:before, q:after {
        content: '';
        content: none;
    }
    table {
        border-collapse: collapse;
        border-spacing: 0;
    }
`;
  • 二、在 src/App.js'中(通常是最外層組件),引入剛剛定義的 GlobalStyle ,而後將<GlobalStyle /> 組件放在 render() 中最外層元素下面
import React from 'react';
import { GlobalStyle } from './style';
import Header from './common/header';

function App() {
  return (
    <div>
      <GlobalStyle />
      <Header />
    </div>
  );
}

export default App;

像這樣引用好以後,就能夠正常使用全局樣式啦

上面是使用styled-components工具定義全局樣式的方法,那麼定義局部樣式該如何使用呢?(這裏只介紹最簡單的用法,具體能夠參考官網)
在Header組件所處的文件夾下新建一個本身的樣式文件style.js

import styled from 'styled-components';
export const HeaderWrapper = styled.div`
    position: relative;
    height: 56px;
    border-bottom: 1px solid #f0f0f0;
    background: red;
`;

上面咱們導出了一個標籤div,這個標籤中帶有一些樣式,使用styled-components後這個標籤也變成了一個組件HeaderWrapper並已導出,接着咱們在Header組件中就可使用這個組件了

import React, { Component } from 'react';
import {
    HeaderWrapper
} from './style';

class Header extends Component {
    render() {
        return (
            <HeaderWrapper>
                111
            </HeaderWrapper>
        )
    }
}

export default Header;

返回頁面能夠看到,樣式生效
圖片描述

而且經過這種方式生成的樣式名是隨機的,這樣就不會出現樣式名衝突的問題,而且這個標籤組件HeaderWrapper只在當前Header組件中使用。那麼樣式就只會在這個Header組件中生效
圖片描述

(3)、使用JS 來管理樣式模塊

使用JS編譯原生的CSS文件,使其具有模塊化的能力,表明是CSS Modules

CSS Modules不是將CSS改造的具備編程能力,而是加入了局部做用域、依賴管理,這偏偏解決了最大的痛點。能夠有效避免全局污染和樣式衝突,能最大化地結合現有 CSS 生態和 JS 模塊化能力

webpack 自帶的 css-loader 組件,自帶了 CSS Modules,經過簡單的配置便可使用

在React腳手架工具中,咱們經過npm run eject將webpack配置文件暴露出來,找到webpack.config.js文件,在這個地方加上這句
圖片描述

修改webpack配置以後咱們須要重啓服務,返回頁面能夠看到以前經過這種方式引入的樣式就不生效了import './style.css';
圖片描述

如今咱們要使用須要經過這樣引入

import styles from './style.css';

而後在下面經過這樣的方式使用

const App = () => {
  return (
    <div>
      <p className={styles.aaa}>hello</p>
      <Child />
    </div>
  )
}

一樣在Child中

import React from 'react';
import styles from './style1.css';

const Child = () => {
  return (
    <div>
      <p className={styles.aaa}>child</p>
    </div>
  )
}
    
export default Child;

刷新頁面,能夠看到雖然兩個文件中的樣式名都是aaa,可是如今他們之間互不影響
圖片描述

這是由於CSS Modules 對 CSS 中的 class 名都作了處理,使用對象來保存原 class 和混淆後 class 的對應關係。CSS Modules自動生成的class類名基本就是惟一的,大大下降了項目中樣式覆蓋衝突的概率。

關於CSS Module更詳細的介紹能夠參考這篇博客( https://segmentfault.com/a/11...
相關文章
相關標籤/搜索