每個(gè)前端都需要知道這些面向未來的CSS技術(shù)
點(diǎn)擊上方 前端Q,關(guān)注公眾號(hào)
回復(fù)加群,加入前端Q技術(shù)交流群
寫在前面
前端技術(shù)日新月異,我們需要不斷學(xué)習(xí)來更新自己的前端知識(shí)并運(yùn)用到自己的項(xiàng)目中。這次筆者整理一些未來普及或者現(xiàn)在同學(xué)們可能已經(jīng)用到的CSS特性,包括SVG圖標(biāo)、滾動(dòng)特性、CSS自定義屬性、CSS現(xiàn)代偽類 、JS in CSS、Web Layout、混合模式和濾鏡、CSS計(jì)數(shù)器等等。
滾動(dòng)特性
在能用CSS實(shí)現(xiàn)的就不用麻煩JavaScript[1]文章提及到滾動(dòng)捕捉的特性,更多有關(guān)于容器滾動(dòng)方面的CSS新特性其實(shí)還有有很多個(gè),比如:
-
自定義滾動(dòng)條的外觀 -
scroll-behavior指容容器滾動(dòng)行為,讓滾動(dòng)效果更絲滑 -
overscroll-behavior優(yōu)化滾動(dòng)邊界,特別是可以幫助我們滾動(dòng)的穿透
自定義滾動(dòng)條的外觀
默認(rèn)的window外觀和mac外觀
windows
mac
在CSS中,我們可以使用-webkit-scrollbar來自定義滾動(dòng)條的外觀。該屬性提供了七個(gè)偽元素:
-
::-webkit-scrollbar:整個(gè)滾動(dòng)條 -
::-webkit-scrollbar-button:滾動(dòng)條上的按鈕(下下箭頭) -
::-webkit-scrollbar-thumb:滾動(dòng)條上的滾動(dòng)滑塊 -
::-webkit-scrollbar-track:滾動(dòng)條軌道 -
::-webkit-scrollbar-track-piece:滾動(dòng)條沒有滑塊的軌道部分 -
::-webkit-scrollbar-corner:當(dāng)同時(shí)有垂直和水平滾動(dòng)條時(shí)交匯的部分 -
::-webkit-resizer:某些元素的交匯部分的部分樣式(類似textarea的可拖動(dòng)按鈕)
html {
--maxWidth:1284px;
scrollbar-color: linear-gradient(to bottom,#ff8a00,#da1b60);
scrollbar-width: 30px;
background: #100e17;
color: #fff;
overflow-x: hidden
}
html::-webkit-scrollbar {
width: 30px;
height: 30px
}
html::-webkit-scrollbar-thumb {
background: -webkit-gradient(linear,left top,left bottom,from(#ff8a00),to(#da1b60));
background: linear-gradient(to bottom,#ff8a00,#da1b60);
border-radius: 30px;
-webkit-box-shadow: inset 2px 2px 2px rgba(255,255,255,.25),inset -2px -2px 2px rgba(0,0,0,.25);
box-shadow: inset 2px 2px 2px rgba(255,255,255,.25),inset -2px -2px 2px rgba(0,0,0,.25)
}
html::-webkit-scrollbar-track {
background: linear-gradient(to right,#201c29,#201c29 1px,#100e17 1px,#100e17)
}
復(fù)制代碼
通過這幾個(gè)偽元素,可以實(shí)現(xiàn)你自己喜歡的滾動(dòng)條外觀效果,比如下面這個(gè)示例:
完整演示[2]
css自定義屬性
你大概已經(jīng)聽說過CSS自定義屬性,也被稱為 CSS 變量,估計(jì)熟悉SCSS、LESS就會(huì)很快上手,概念大同小異,都是讓我們的CSS變得可維護(hù),目前Edge最新版都已經(jīng)支持這個(gè)特性了,這說明現(xiàn)在 CSS 自定義屬性已經(jīng)能用在實(shí)際項(xiàng)目中了,相信不久以后開發(fā)者們將大大依賴這個(gè)特性。但還請(qǐng)?jiān)谑褂弥罢?qǐng)先檢查一下本文附錄中 Postcss 對(duì)于 CSS 自定義屬性的支持情況,以便做好兼容。
什么是自定義屬性呢?簡單來說就是一種開發(fā)者可以自主命名和使用的 CSS 屬性。瀏覽器在處理像 color 、position 這樣的屬性時(shí),需要接收特定的屬性值,而自定義屬性,在開發(fā)者賦予它屬性值之前,它是沒有意義的。所以要怎么給 CSS 自定義屬性賦值呢?這倒和習(xí)慣無異
.foo {
color: red;
--theme-color: gray;
}
復(fù)制代碼
自定義元素的定義由 -- 開頭,這樣瀏覽器能夠區(qū)分自定義屬性和原生屬性,從而將它倆分開處理。假如只是定義了一個(gè)自定義元素和它的屬性值,瀏覽器是不會(huì)做出反應(yīng)的。如上面的代碼, .foo 的字體顏色由 color 決定,但 --theme-color 對(duì) .foo 沒有作用。
你可以用 CSS 自定義元素存儲(chǔ)任意有效的 CSS 屬性值
.foo {
--theme-color: blue;
--spacer-width: 8px;
--favorite-number: 3;
--greeting: "Hey, what's up?";
--reusable-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.85);
}
復(fù)制代碼
使用
假如自定義屬性只能用于設(shè)值,那也太沒用了點(diǎn)。至少,瀏覽器得能獲取到它們的屬性值。
使用 var() 方法就能實(shí)現(xiàn):
.button {
background-color: var(--theme-color);
}
復(fù)制代碼
下面這段代碼中,我們將 .button 的 background-color 屬性值賦值為 --theme-color 的值。這例子看起來自定義屬性也沒什么了不起的嘛,但這是一個(gè)硬編碼的情況。你有沒有意識(shí)到,--theme-color 的屬性值是可以用在任意選擇器和屬性上的呢?這可就厲害了。
.button {
background-color: var(--theme-color);
}
.title {
color: var(--theme-color);
}
.image-grid > .image {
border-color: var(--theme-color);
}
復(fù)制代碼
缺省值
如果開發(fā)者并沒有定義過 --theme-color 這個(gè)變量呢?var() 可以接收第二個(gè)參數(shù)作為缺省值:
.button {
background-color: var(--theme-color, gray);
}
復(fù)制代碼
注意:如果你想把另一個(gè)自定義屬性作為缺省值,語法應(yīng)該是 background-color: var(--theme-color, var(--fallback-color))
傳參數(shù)時(shí)總是傳入一個(gè)缺省值是一個(gè)好習(xí)慣,特別是在構(gòu)建 web components 的時(shí)候。為了讓你的頁面在不支持自定義屬性的瀏覽器上正常顯示,別忘了加上兼容代碼:
.button {
background-color: gray;
background-color: var(--theme-color, gray);
}
復(fù)制代碼
CSS現(xiàn)代偽類
這些最新的偽類特性,我們也需要知道。
使用 :is() 減少重復(fù)
你可以使用 :is() 偽類來刪除選擇器列表中的重復(fù)項(xiàng)。
/* BEFORE */
.embed .save-button:hover,
.attachment .save-button:hover {
opacity: 1;
}
/* AFTER */
:is(.embed, .attachment) .save-button:hover {
opacity: 1;
}
復(fù)制代碼
此功能主要在未處理的標(biāo)準(zhǔn)CSS代碼中有用。如果使用Sass或類似的CSS預(yù)處理程序,則可能更喜歡嵌套。
注意:瀏覽器還支持非標(biāo)準(zhǔn)的 :-webkit-any() 和 :-moz-any() 偽類,它們與 :is() 相似,但限制更多。WebKit在2015年棄用了 :-webkit-any() ,Mozilla已將Firefox的用戶代理樣式表更新為使用 :is() 而不是 :-moz-any()。
使用 :where() 來保持低特殊性
:where() 偽類與 :is() 具有相同的語法和功能。它們之間的唯一區(qū)別是 :where() 不會(huì)增加整體選擇器的特殊性(即某條CSS規(guī)則特殊性越高,它的樣式越優(yōu)先被采用)。
:where()偽類及其任何參數(shù)都不對(duì)選擇器的特殊性有所幫助,它的特殊性始終為零
此功能對(duì)于應(yīng)易于覆蓋的樣式很有用。例如,基本樣式表 sanitize.css 包含以下樣式規(guī)則,如果缺少 <svg fill> 屬性,該規(guī)則將設(shè)置默認(rèn)的填充顏色:
svg:not([fill]) {
fill: currentColor;
}
復(fù)制代碼
由于其較高的特殊性(B = 1,C = 1),網(wǎng)站無法使用單個(gè)類選擇器(B = 1)覆蓋此聲明,并且被迫添加 !important 或人為地提高選擇器的特殊性(例如 .share- icon.share-icon)。
.share-icon {
fill: blue; /* 由于特殊性較低,因此不適用 */
}
復(fù)制代碼
CSS庫和基礎(chǔ)樣式表可以通過用 :where() 包裝它們的屬性選擇器來避免這個(gè)問題,以保持整個(gè)選擇器的低特殊性(C=1)。
/* sanitize.css */
svg:where(:not([fill])) {
fill: currentColor;
}
/* author stylesheet */
.share-icon {
fill: blue; /* 由于特殊性較高,適用 */
}
復(fù)制代碼
其它新偽類特性有情趣同學(xué)可以按照導(dǎo)圖查閱一下相關(guān)文檔資料。
完整演示[3]
JS in CSS
前面提到過,使用CSS自定義屬性的時(shí)候,可以通過JavaScript來操作自定義屬性的值。其實(shí)還可以更強(qiáng)大一點(diǎn),如果你對(duì)CSS Houdini熟悉的話,可以借助其特性,直接在CSS的代碼中來操作CSS自定義屬性
:root {
--property: document.write('hello world!');
}
復(fù)制代碼
window.onload = () => {
const doc = window.getComputedStyle(document.documentElement);
const cssProp = doc.getPropertyValue('--property');
new Function((cssProp))();
}
復(fù)制代碼
完整演示[4]
Web layout
對(duì)于Web布局而言,前端就一直在探討這方面的最優(yōu)方式。早期的table布局,接著的float和position相關(guān)的布局,多列布局,F(xiàn)lexbox布局和Grid布局等。Flexbox和Grid的出現(xiàn),Web布局的靈活性越來越高。
如圖不依賴媒體查詢實(shí)現(xiàn)自動(dòng)計(jì)算
CSS Grid中提供了很多強(qiáng)大的特性,比如:
-
fr單位,可以很好的幫助我們來計(jì)算容器可用空間 -
repeat()函數(shù),允許我們給網(wǎng)格多個(gè)列指定相同的值。它也接受兩個(gè)值:重復(fù)的次婁和重復(fù)的值 -
minmax()函數(shù),能夠讓我們用最簡單的CSS控制網(wǎng)格軌道的大小,其包括一個(gè)最小值和一個(gè)最大值 -
auto-fill和auto-fit,配合repeat()函數(shù)使用,可以用來替代重復(fù)次數(shù),可以根據(jù)每列的寬度靈活的改變網(wǎng)格的列數(shù) -
max-content和min-content,可以根據(jù)單元格的內(nèi)容來確定列的寬度 -
grid-suto-flow,可以更好的讓CSS Grid布局時(shí)能自動(dòng)排列
結(jié)合這些功能點(diǎn),布局會(huì)變得更輕松。比如我們要實(shí)現(xiàn)一個(gè)響應(yīng)式的布局,很多時(shí)候都會(huì)依賴于媒體查詢(@media)來處理,事實(shí)上,有了CSS Grid Layout之后,這一切變得更為簡單,不需要依賴任何媒體查詢就可以很好的實(shí)現(xiàn)響應(yīng)式的布局。特別是當(dāng)今這個(gè)時(shí)代,要面對(duì)的終端設(shè)備只會(huì)增加不會(huì)減少,那么希望布局更容易的適配這些終端的布局,那么CSS Grid Layout將會(huì)起到很大的作用。
完整示例[5]
Grid和flex都是面向未來的最佳布局方案。我們不應(yīng)該探討誰優(yōu)誰劣,而是應(yīng)該取長補(bǔ)短結(jié)合使用。
混合模式和濾鏡
能用CSS實(shí)現(xiàn)的就不用麻煩JavaScript — Part2[6]一文提到混合模式。CSS混合模式和濾鏡主要是用來處理圖片的。熟悉PS之類軟件的同學(xué)很容易理解里面的屬性。
完整代碼演示[7]
CSS計(jì)數(shù)器
CSS計(jì)數(shù)器其實(shí)涉及到三個(gè)屬性:counter-increment、counter-reset和counter()。一般情況都是配合CSS的偽元素::before和::after的content一起使用。可以用來計(jì)數(shù)
完整演示[8]
SVG圖標(biāo)
對(duì)于SVG而言,它是一套獨(dú)立而又成熟的體系,也有自己的相關(guān)規(guī)范(Scalable Vecgtor Graphics 2),即 SVG2。雖然該規(guī)范已經(jīng)存在很久了,但很多有關(guān)于SVG相關(guān)的特性在不同的瀏覽器中得到的支持度也是有所不一致的。特別是SVG中的漸變和濾鏡相關(guān)的特性。不過,隨著技術(shù)的革新,在Web的應(yīng)用當(dāng)中SVG的使用越來越多,特別是SVG 圖標(biāo)相關(guān)的方面的運(yùn)用。
-
最早通過
<img>標(biāo)簽來引用圖標(biāo)(每個(gè)圖標(biāo)一個(gè)文件) -
為了節(jié)省請(qǐng)求,提出了Sprites的概念,即將多個(gè)圖標(biāo)合并在一起,使用一個(gè)圖片文件,借助
background相關(guān)的屬性來實(shí)現(xiàn)圖標(biāo) -
圖片畢竟是位圖,面對(duì)多種設(shè)備終端,或者說更易于控制圖標(biāo)顏色和大小,開始在使用Icon Font來制作Web圖標(biāo)
-
當(dāng)然,字體圖標(biāo)是解決了不少問題,但每次針對(duì)不同的圖標(biāo)的使用,需要自定義字體,也要加載相應(yīng)的字體文件,相應(yīng)的也帶了一定的問題,比如說跨域問題,字體加載問題
-
隨著SVG的支持力度越來越強(qiáng),大家開始在思考SVG,使用SVG來制作圖標(biāo)。該技術(shù)能解決我們前面碰到的大部分問題,特別是在而對(duì)眾多終端設(shè)備的時(shí)候,它的優(yōu)勢越發(fā)明顯
-
SVG和 img有點(diǎn)類似,我們也可以借助<symbol>標(biāo)簽和<use>標(biāo)簽,將所有的SVG圖標(biāo)拼接在一起,有點(diǎn)類似于Sprites的技術(shù),只不過在此稱為SVG Sprites
<!-- HTML -->
<svg width="0" height="0" display="none" xmlns="http://www.w3.org/2000/svg">
<symbol id="half-circle" viewBox="0 0 106 57">...</symbol>
<!-- .... -->
<symbol id="icon-burger" viewBox="0 0 24 24">...</symbol>
</svg>
復(fù)制代碼
SVG Sprites和img Sprites有所不同,SVG Sprites就是一些代碼(類似于HTML一樣),估計(jì)沒有接觸過的同學(xué)會(huì)問,SVG Sprites對(duì)應(yīng)的代碼怎么來獲取呢?其實(shí)很簡單,可以借助一些設(shè)計(jì)軟件來完成,比如Sketch。當(dāng)然也可以使用一些構(gòu)建工具,比如說svg-sprite。有了這個(gè)之后,在該使用的地方,使用<use>標(biāo)簽,指定<symbol>中相應(yīng)的id值即可,比如:
<svg class="icon-nav-articles" width="26px" height="26px">
<use xlink:href="#icon-nav-articles"></use>
</svg>
復(fù)制代碼
使用SVG的圖標(biāo)還有一優(yōu)勢,我們可以在CSS中直接通過代碼來控制圖標(biāo)的顏色:
.site-header .main-nav .main-sections>li>a>svg {
// ...
fill: none;
stroke-width: 2;
stroke: #c2c2c2;
}
.site-header .main-nav:hover>ul>li:nth-child(1) svg {
stroke: #ff8a00;
}
復(fù)制代碼
完整演示[9]
寫在最后
以上列舉都是CSS一些優(yōu)秀的特性。還有很多,有時(shí)間再收集更多分享給大家。這些新特性在不同的瀏覽器中差異性是有所不同的。但這并不是阻礙我們?nèi)W(xué)習(xí)和探索的原因所在。我們應(yīng)該及時(shí)去了解并運(yùn)用到,才可以做到對(duì)項(xiàng)目精益求精。
關(guān)于本文
作者:李振文
https://juejin.cn/post/6989513390636924936
內(nèi)推社群
我組建了一個(gè)氛圍特別好的騰訊內(nèi)推社群,如果你對(duì)加入騰訊感興趣的話(后續(xù)有計(jì)劃也可以),我們可以一起進(jìn)行面試相關(guān)的答疑、聊聊面試的故事、并且在你準(zhǔn)備好的時(shí)候隨時(shí)幫你內(nèi)推。下方加 winty 好友回復(fù)「面試」即可。
