成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何優(yōu)雅地覆蓋組件庫樣式?

開發(fā) 前端
本文通過如何修改UI組件內(nèi)部樣式為切入點(diǎn),分析了幾種解法。了解了組合選擇器的優(yōu)先級分?jǐn)?shù)累加,以及在實(shí)際React、Vue項(xiàng)目用到的樣式隔離方案——CSS Module和Scoped的原理,最后是介紹了在樣式隔離的情況下,如何使用:global和深度作用選擇器做樣式覆蓋。

大家好,我是年年!組件庫的樣式覆蓋不掉,這應(yīng)該是很多前端在工作中遇到過的問題。今天從實(shí)際案例出發(fā)分析原因,最后會給出在React和Vue項(xiàng)目中的最優(yōu)解。

本文會講清:

  • React中CSS Module的原理是什么?:global是做什么的?
  • Vue中Scoped的原理是什么?深度作用選擇器是什么?

先不講概念,直接從需求出發(fā):我使用了Antd組件庫來展示一個(gè)日歷。

現(xiàn)在我想將當(dāng)前日期上面的藍(lán)色邊框變成紫色。

可以試試你能不能實(shí)現(xiàn)。

不管是React還是Vue,整個(gè)Calendar是被封裝起來的,我們沒有辦法在組件外簡單加上style/class改動內(nèi)部的樣式。

import { Calendar } from 'antd';
...
<div className="myWrapper">
<Calendar class="custom"/>
</div>

定位要覆蓋的樣式

首先用開發(fā)者工具定位對應(yīng)的樣式:.ant-picker-calendar-date-today,這就是我們要修改的地方。

.ant-picker-calendar-full .ant-picker-panel .ant-picker-calendar-date-today {
border-color: #1890ff;
}

熟悉webpack的人應(yīng)該知道,引入的CSS文件最終都會被style-loader處理。簡單來說,它的作用就是把CSS文件打包,放在style標(biāo)簽內(nèi),最后塞進(jìn)HTML中作為一個(gè)內(nèi)部樣式表。不管是組件庫的樣式還是我們寫的自定義樣式都是這樣處理的。

我們要把組件庫的樣式先于自定義樣式引入,這樣自定義樣式才能有更高的優(yōu)先級。

修改源文件

直接改組件庫的CSS源碼是最簡單粗暴的方法。打開你項(xiàng)目的node_modules文件夾,一層層點(diǎn)開,找到對應(yīng)樣式文件,按照需求修改即可。

個(gè)人項(xiàng)目這樣處理確實(shí)可行,但是團(tuán)隊(duì)合作時(shí),同步別人本地的node_modules就比較麻煩,只能算一個(gè)60分解法。

全局CSS文件

之前提到,把自己寫的的CSS文件放在組件庫的樣式后面,可以保障自定義有更高優(yōu)先級。只要重寫同名的樣式,理論上就能實(shí)現(xiàn)覆蓋組了。

但這樣??處理會發(fā)現(xiàn)并不起作用:

/* src/demo.css */
.ant-picker-calendar-date-today {
border-color: purple; /* 覆蓋為紫色 */
}
// src/Demo.js

// 組件庫的樣式
import 'ant-design-vue/dist/antd.css';
// 自定義樣式
import './demo.css'
import { Calendar } from 'antd';
...
<div className="myWrapper">
<Calendar />
</div>
...

...

因?yàn)檫@里還涉及CSS組合選擇器的優(yōu)先級。

基礎(chǔ)的優(yōu)先級應(yīng)該不用贅述:!important>內(nèi)聯(lián)樣式>ID選擇器>類選擇器>標(biāo)簽選擇器。(!important這種hack會導(dǎo)致項(xiàng)目不好維護(hù),不提倡使用)

在這個(gè)基礎(chǔ)上還有五種組合選擇器要對優(yōu)先級分?jǐn)?shù)做累計(jì),以類選擇器為例:

  • 后代選擇器(空格):.A .B,選擇.A元素后的所有.B元素,
  • 子元素選擇器(大于號):.A>.B,選擇.A元素的直接后代中的.B元素
  • 相鄰兄弟選擇器(加號):.A+.B,選擇.A元素后緊鄰的第一個(gè)兄弟.B元素
  • 后續(xù)兄弟選擇器(~號):.A~.B,選擇.A元素后所有的兄弟.B元素
  • 交集選擇器(連在一起):.A.B選擇自身同時(shí)擁有.A和.B兩個(gè)屬性的元素

上面幾個(gè)規(guī)則看著很復(fù)雜,其實(shí)用的多的就是第一個(gè)后代選擇器,記住它就行。Antd組件庫用的就是它:

.ant-picker-calendar-full .ant-picker-panel .ant-picker-calendar-date-today {
border-color: #1890ff;
}

如果說一個(gè)類選擇器優(yōu)先級分?jǐn)?shù)是10分,那三個(gè)形成的后代選擇器就是30分。

而自定義的樣式??只有10分,所以即使放在更后面引入,也不能成功覆蓋。

.ant-picker-calendar-date-today {
border-color: purple; // 覆蓋為紫色
}

需要完整重寫整個(gè)選擇器才能實(shí)現(xiàn)想要的效果。

這里補(bǔ)充一點(diǎn),同樣也是組合選擇器,但并集選擇器(逗號)優(yōu)先級不累計(jì):.A, .B,選擇.A或者.B元素(可以是逗號+空格)

樣式隔離CSS Module和Scoped

上面我們引入自定義的全局CSS文件,實(shí)現(xiàn)了樣式的覆蓋,但是這種解法只能給80分。因?yàn)樵趯?shí)際工作中,項(xiàng)目Owner通常不允許使用全局CSS,這會造成樣式污染:你定義了一個(gè)樣式my_button,團(tuán)隊(duì)其他人恰巧也命名為my_button,這就造成樣式?jīng)_突。

我們需要給每個(gè)文件做樣式隔離,就好像是給它一個(gè)命名空間。通常使React項(xiàng)目使用的是用的是CSS Module,Vue項(xiàng)目使用Scoped標(biāo)記。

接下來會講清兩種樣式隔離的原理,以及使用樣式隔離時(shí)怎么覆蓋組件庫的樣式。

React的CSS Module

首先來了解一下CSS Module的原理。它的使用很簡單,在CSS文件加一個(gè)后綴.module,然后當(dāng)做一個(gè)變量引入到JS文件中。

// src/Demo.js
import styles from './demo.module.css';
export default function Demo() {
return (
<div className={styles.myWrapper}>
<Calendar />
</div>
);
}
/* src/demo.module.css */
.myWrapper {
border: 5px solid black;
}

被編譯后??,插入的樣式表和元素的class屬性都會加上一個(gè)哈希值作為命名空間。

<style>
.demo_myWrapper__Hd9Qg {
border: 5px solid black;
}
</style>
<div class="demo_myWrapper__Hd9Qg">
...
</div>

可以看到,原本的CSS選擇器和HTML元素類名都從myWrapper變成了demo_myWrapper__Hd9Qg,前面加上了文件名,后面加上了哈希值,這樣就能保障樣式只在當(dāng)前這個(gè)文件下生效了。

但是在這種樣式隔離情況下,我們原本用作覆蓋的CSS也被加上了哈希值,就像下圖這樣,這時(shí)沒有辦法選中UI組件,覆蓋也就不會成功。

所以,React給我們提供了一個(gè)語法:global。它生效范圍內(nèi)的樣式會被當(dāng)作全局CSS。

具體使用如下,在CSS文件中,使用:global包裹希望全局生效的樣式

:global(.ant-picker-calendar-full .ant-picker-panel .ant-picker-calendar-date-today) {
border-color:purple; /* 覆蓋為紫色 */
}

SCSS或SASS中,還可以使用嵌套語法:

:global {
.ant-picker-calendar-full .ant-picker-panel .ant-picker-calendar-date-today {
border-color:purple;
}
}

最后編譯出來的代碼如下:

/* 加上了哈希*/
.demo_myWrapper__Hd9Qg {
border: 5px solid black;
}
/* :global作用域下都不會加上哈希*/
.ant-picker-calendar-full .ant-picker-panel .ant-picker-calendar-date-today {
border-color:purple;
}

借助:global語法,即使使用CSS Module進(jìn)行樣式隔離也可以如愿實(shí)現(xiàn)覆蓋功能。

Vue中的Scoped

Vue中也有類似的樣式隔離功能,使用Scoped標(biāo)記CSS部分,使用也很簡單??:

<style scoped>
.myWrapper{
border: 5px solid black
}
</style>
...
<div class="myWrapper" >
<Calendar />
</div>
...

編譯出來的代碼如下??:

<style>
.myWrapper[data-v-2fc5154c] {
border: 5px solid black
}
</style>
<div class="myWrapper" data-v-2fc5154c>
...
</div>

可以看到,它的原理和CSS Module不太一樣,Vue的Scoped會使CSS選擇器后加上一個(gè)中括號。

這并不是Vue獨(dú)創(chuàng)的語法,而是屬性選擇器。.myWrapper[data-v-2fc5154c]代表選擇擁有data-v-2fc5154c這個(gè)屬性的、同時(shí)是myButton類的HTML元素。只有這個(gè)文件內(nèi)部的HTML元素才會被打上data-v-2fc5154c這個(gè)屬性。其余文件的HTML元素即使是myWrapper類,這個(gè)樣式也不會對他生效。

回到相同的問題,假如Vue項(xiàng)目在使用了Scoped做樣式隔離,我們用于覆蓋的樣式也會加上屬性選擇器,但是UI組件內(nèi)部的HTML元素都沒有該屬性??。

所以Vue提供了一個(gè)類似的語法:深度作用選擇器。

使用很簡單,把要“滲透“進(jìn)組件內(nèi)部的樣式前面加上>>>,作用域內(nèi)的CSS樣式都不會帶上哈希值作為屬性選擇器。

<style scoped>
.myWrapper>>>
.ant-picker-calendar-full
.ant-picker-panel
.ant-picker-calendar-date-today{
border-color:purple
}
</style>
<template>
<div class="myWrapper" >
<Calendar />
</div>
</template>

編譯后??

<style>
.myWrapper[data-v-2fc5154c]
.ant-picker-calendar-full
.ant-picker-panel
/* 作用域內(nèi)的CSS都沒有帶上屬性選擇器 */
.ant-picker-calendar-date-today {
border-color:purple
}
</style>

<div class="myWrapper" data-v-2fc5154c>
<div class="ant-picker-calendar-full" data-v-2fc5154c>
<div class="ant-picker-date-panel">
<td class="ant-picker-cell-today"></td>
</div>
</div>
</div>

借助深度作用選擇器,可以將要用于覆蓋CSS“滲透”進(jìn)組件內(nèi)部。

也可以將>>>寫成/deep/或者::v-deep。

相較于React的:global,Vue的深度作用選擇器是一種更優(yōu)秀的方案,它必須要一個(gè)前導(dǎo)(也就是上面例子中的.myWrapper選擇器),前導(dǎo)依舊會被打上哈希值作為屬性選擇器,要滲透進(jìn)去的樣式實(shí)際上是作為它的子選擇器,只在當(dāng)前這個(gè)文件下生效,徹底避免造成全局污染。

結(jié)語

本文通過如何修改UI組件內(nèi)部樣式為切入點(diǎn),分析了幾種解法。了解了組合選擇器的優(yōu)先級分?jǐn)?shù)累加,以及在實(shí)際React、Vue項(xiàng)目用到的樣式隔離方案——CSS Module和Scoped的原理,最后是介紹了在樣式隔離的情況下,如何使用:global和深度作用選擇器做樣式覆蓋。

責(zé)任編輯:武曉燕 來源: 前端私教年年
相關(guān)推薦

2021-03-24 10:20:50

Fonts前端代碼

2024-11-13 16:37:00

Java線程池

2020-03-26 11:04:00

Linux命令光標(biāo)

2021-01-18 13:17:04

鴻蒙HarmonyOSAPP

2021-05-12 22:07:43

并發(fā)編排任務(wù)

2022-05-24 06:07:48

JShack用戶代碼

2021-01-28 14:53:19

PHP編碼開發(fā)

2024-04-24 12:34:08

Spring事務(wù)編程

2020-10-22 10:15:33

優(yōu)化Windows電腦

2021-09-08 08:34:37

Go 文檔Goland

2023-02-13 14:37:13

開發(fā)web瀏覽器

2020-12-08 08:08:51

Java接口數(shù)據(jù)

2018-08-20 10:40:09

Redis位圖操作

2020-07-09 10:15:55

空值Bug語言

2020-09-25 11:30:20

Java判空代碼

2020-11-06 08:13:03

服務(wù)器Nodejs客戶端

2021-03-26 20:37:14

Prometheus監(jiān)控指標(biāo)

2017-12-14 14:17:08

Windows使用技巧手冊

2020-02-05 14:05:21

Java技術(shù)數(shù)組

2020-04-10 10:22:12

Java判空編程語言
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 午夜精品久久久久久久 | 懂色中文一区二区三区在线视频 | 99久久久无码国产精品 | 一区二区三区四区在线视频 | 久草网视频| 国产日韩欧美一区二区 | 国产成人精品一区二区三区在线观看 | 国产亚洲欧美另类一区二区三区 | 在线观看精品 | 一区二区三区精品视频 | 国产欧美精品一区二区色综合 | 东京av男人的天堂 | 精品久久久久久久久久久久久久 | 欧美日韩综合 | 国产高清视频在线观看播放 | 午夜小视频免费观看 | 日日天天| 国产成人精品一区二 | 国产在线一区二区三区 | 精品美女在线观看 | 国产1区2区在线观看 | 欧美一级特黄aaa大片在线观看 | 亚洲精品国产电影 | 日韩成人免费视频 | 欧美一区二区三区的 | 国产高清视频在线 | 日本不卡免费新一二三区 | 午夜手机在线视频 | 成人欧美一区二区三区在线播放 | 国产香蕉视频在线播放 | 中国黄色在线视频 | 先锋资源在线 | 不卡一区二区三区四区 | 一二三四在线视频观看社区 | a级片在线 | 美女爽到呻吟久久久久 | 欧美一级艳情片免费观看 | 欧美啪啪| 给我免费的视频在线观看 | 精品中文字幕一区 | 中文字幕视频在线免费 |