前端(vue)入門到精通課程:進入學(xué)習(xí)
可能我們有時候潛意識里認為, 當前實際開發(fā)中css
屬性已經(jīng)足夠用了, 但是前段時間突然想到:"會不會我們只是思維被限制在了常用的css屬性中, 從而喪失了創(chuàng)造力", 就像發(fā)明 車
之前大多數(shù)人會認為 騎馬
已經(jīng)足夠快可以滿足自己的需求了, 所以我專門整理了一下自己的學(xué)習(xí)筆記并且專門去學(xué)習(xí)了一些冷門的css
屬性, 果然收獲滿滿, 所以今天也要在這里把這些腦洞大開的屬性較少給你, 準備好一起來感受css
的魅力吧。
一、開胃菜 css畫背景圖: paint
??? 我們開發(fā)中使用的背景圖大部分是(png, webp等)圖片
、svg矢量圖
、canvas畫圖
, 但是其實我們也可以選擇css
直接畫圖, 那css
這種甚至都"稱不上"編程語言的家伙怎么繪制復(fù)雜的圖片那?【推薦學(xué)習(xí):css視頻教程】
1: 為元素賦予css屬性
div class="box"></div>
.box { width: 180px; height: 180px; border: 1px solid; background: paint(xxxx); // 主角在此 }
??? paint(xxxx);
這里填入的是繪圖的"方法名", 往下看就知道啥是"方法名"了, 之所以我這里寫"xxxx"非常隨意, 是因為我想表達這個名字隨便起。
2: 引入js文件
<script> if (window.CSS) { // 因為加載文件 需要啟動server CSS.paintWorklet.addModule("./paint-grid.js"); } </script>
??? 用法有點詭異, 但核心其實是引入了一個js文件
。
3: js文件內(nèi)定義導(dǎo)出的方法
??? paint-grid.js
文件:
registerPaint( "xxxx", // 這就是: 方法名 class { paint(context, size) { context.fillStyle = 'red'; context.fillRect(10, 10, 39, 39); } } );
??? paint
方法里面就類似canvas
了, 可以正常使用部分js
代碼。
??? 當前的效果展示:
4: 可多導(dǎo)出
??? 當看到需要指定繪制的"方法名"而不是"文件名", 我就知道他一定可以導(dǎo)出多個嘍:
registerPaint( "xxxx1", class { paint(context, size) { context.fillStyle = 'red'; context.fillRect(10, 10, 39, 39); } } ); registerPaint( "xxxx2", class { paint(context, size) { context.fillStyle = 'green'; context.fillRect(10, 10, 39, 39); } } );
兩個元素的樣式設(shè)置
.box { background: paint(xxxx1); } .box2 { margin-top: 20px; background: paint(xxxx2); }
5: 變量賦予背景靈動
??? 我們時長遇到需要繪制"非固定大小背影", 此時在paint-grid.js
中window
是獲取不到的, 但是我們可以使用css變量
:
// 在全局定義方便js修改 :root { --bg-size: 60; }
??? paint-grid.js
文件
registerPaint( "xxxx1", class { static get inputProperties() { return ["--bg-size"]; } paint(context, size, properties) { var bgSize = properties.get('--bg-size'); context.fillStyle = "red"; context.fillRect(10, 10, bgSize, bgSize); } } );
??? inputProperties
定義了需要獲取哪些屬性, paint
的第三個參數(shù)可以接收這些屬性, 這樣瞬間就感覺這個屬性還有點用啦。
6: 注意事項
-
不能在
js
文件的繪制方法里面寫alert
, 會導(dǎo)致報錯阻斷繪制: -
要注意維護
paint-grid.js
文件與css
文件的相關(guān)性, 因為大家寫代碼會下意識的不會認為js
方法被css
文件里的屬性所使用, 這就導(dǎo)致可能后續(xù)無刪除或者是不敢刪除等問題。 -
適合處理簡單的圖形, 如果復(fù)雜度高了或者還需借助其他"庫"的情況, 則不建議使用。
二、字體三連 (鏤空、漸變、背景)
1: 鏤空字不算罕見
p { font-size: 150px; color: white; -webkit-text-stroke: 6px red; }
2: 漸變色文字
p { font-size: 150px; color: white; -webkit-text-stroke: 6px red; background-color: rosybrown; background-image: -webkit-linear-gradient(top, red, #fd8403, yellow); -webkit-background-clip: text; color: transparent; }
<p> 高 <br> 低 </p>
3: 文字背景
???我們把"白金之星"(jojo的奇妙冒險中的'人物')的圖片作為文字的背景:
div { font-size: 150px; background: url(../imgs/jojo.webp) no-repeat; background-size: 100%; background-origin: border-box; -webkit-background-clip: text; color: transparent; }
??? 這里的關(guān)鍵點是-webkit-background-clip: text
, 意思是將dom
內(nèi)文字以外的區(qū)域裁剪掉, 所以就剩文字區(qū)域了, 然后文字再設(shè)置成透明的。
三、他來了他來了, 他帶著炫酷的過場動畫走來了
??? 先看一下咱們用css
字體屬性做的動動畫效果:
??? 倒計時骨王登場:
??? 這里的思路就是利用文字的背景圖
屬性, 但是難點是如何讓文字變大。
1: 難點與坑點
??? 文字變大有什么難的? 你可能會說這些so簡單, 我們設(shè)置文字所在的span
標簽position: absolute;
定位在父級中間不就OK了? 但是如果這樣設(shè)置就會導(dǎo)致-webkit-background-clip: text;
失效, 也就是文本脫離了文檔流。
??? 有同學(xué)有會想到 transform:scale(1.5);
來動態(tài)控制文字的變大, 但是transform
依然會使-webkit-background-clip: text;
失效。
??? 所以我想到的是在div
中設(shè)置flex
讓文字上下左右居中, 然后調(diào)大font-size
屬性。
??? 還有一個問題就是背景色問題, 因為設(shè)置了背景圖的同時沒法設(shè)置文字外層的背景色。
2: 實現(xiàn)思路
??? 首先總共需要三層結(jié)構(gòu), 第一層wrap
負責黑色背景色以及overflow: hidden;
來截斷我們的文字變大, 第二層box
負責文字的居中, 并且設(shè)置font-size
屬性讓內(nèi)部元素繼承, 第三層span
標簽負責文字①②③的存放, 因為要控制這些文字的顯隱所以需要dom
標簽包裹。
3: 實現(xiàn)代碼
??? 代碼有些粗鄙沒有潤色
<!DOCTYPE html> <html> <head> <style> #wrap { background-color: black; width: 500px; height: 500px; margin: 0 auto; overflow: hidden; } .box0 { background: url(../imgs/jojo.webp) no-repeat; } .box1 { background: url(../imgs/一起干飯.jpeg) no-repeat; } .box2 { background: url(../imgs/gat.webp) no-repeat; } #box { width: 500px; height: 500px; font-size: 150px; margin: 0 auto; background-size: 500px 500px; background-position: center; -webkit-background-clip: text; -webkit-text-fill-color: rgba(0, 0, 0, 0.2); display: flex; justify-content: center; align-items: center; } .text { display: none; } </style> </head> <body> <div id="wrap"> <div id="box"> <span>①</span> <span>②</span> <span>③</span> </div> </div> <script> const oBox = document.getElementById("box"); const textArr = document.getElementsByClassName('text') let i = 0; let n = 800; setInterval(()=>{ oBox.style.fontSize = n + 'px'; n+=3 if(n > 800){ n = 10; textArr[1].style.display = 'none' textArr[2].style.display = 'none' textArr[0].style.display = 'none' textArr[i].style.display = 'block' oBox.classList.remove('box1') oBox.classList.remove('box2') oBox.classList.remove('box3') oBox.classList.add(`box${i}`) i++ if(i > 2){ i = 0 } } },5) </script> </body> </html>
??? 把文案改成 "◤ ◢ ?" 就會出現(xiàn)第一個動圖的效果啦!
四、引號: quotes
??? 所謂引號就相當于給書名加上'書名號', 給語言加上'冒號雙引號', 當然他還有一些神奇玩法。
1: 基本使用
<div class="box">jojo的奇妙冒險</div>
<style> .box { quotes: "《" "》"; } .box::before { content: open-quote; } .box:after { content: close-quote; } </style>
效果圖:
??? 這里要注意的是如果沒寫content: open-quote;
會導(dǎo)致前后'書名號'都消失, 但是唯獨沒寫content: close-quote;
則會保留展示"《"。
2: 看似雞肋?
??? 當前這個基礎(chǔ)寫法也太雞肋了, 不就是給"《"起了個別名叫open-quote
嗎? 并且關(guān)鍵是占用了我的before
與after
, 感覺畫蛇添足, 比如我可以用如下的方法進行替換:
:root { --open: "《"; --close: "》"; } div::before { content: var(--open); } div::after { content: var(--close); }
<div class="box">jojo的奇妙冒險</div>
3: 套娃高手 quotes 雄起
???其實quotes
的看家本領(lǐng)是它可以接受n
個參數(shù)!
.box { quotes: "--- start" "---- end" "《" "》"; } .box::before { content: open-quote; } .box:after { content: close-quote; }
<div class="box"> <div class="box">jojo的奇妙冒險</div> <div class="box">Overlord</div> <div class="box">艾爾登法環(huán)</div> </div>
???神奇的事情出現(xiàn)了, 當出現(xiàn)嵌套結(jié)構(gòu)的時候, 內(nèi)部的元素會使用第三個與第四個參數(shù)作為"引號", 套娃事件
出現(xiàn)啦:
.box { quotes: "--- start" "---- end" "(" ")" "《" "》"; } .box::before { content: open-quote; } .box:after { content: close-quote; }
<div class="box"> <div class="box"> <span class="box">jojo的奇妙冒險</span> </div> <div class="box"> <span class="box">Overlord</span> </div> <div class="box"> <span class="box">艾爾登法環(huán)</span> </div> </div>
??? 說實話這個套娃能力還挺厲害的, 并且我們可以講 close-quote
屬性置空, 我想到的就是列表:
.box { quotes: "--- start" "---- end" "1: " "" "-- 2:" "" "---- 3: " "" "------ 4: " ""; } .box::before { content: open-quote; } .box:after { content: close-quote; }
<div class="box"> <div class="box"> 第一: <div class="box"> 第二: <div class="box">第三:</div> </div> <div class="box"> 第二: <div class="box"> 第三: <div class="box">第四:</div> </div> </div> </div> <div class="box"> 第一: <div class="box">第二:</div> </div> </div>
???要注意不寫close-quote
會讓css
找不到在哪里結(jié)束, 所以最好寫上并給空值。
五、還原大師: all
CSS all 簡寫屬性 將除了 unicode-bidi 與 direction 之外的所有屬性重設(shè)至其初始值,或繼承值。
???這是一個比較強硬的屬性, 可以把幾乎所有css屬性進行重置:
???我們先設(shè)置一下基礎(chǔ)的環(huán)境
.wrap { font-size: 30px; font-weight: 900; } .box { width: 100px; height: 100px; border: 1px solid; background-color: red; color: white; } .box1 { all: initial; } .box2 { all: inherit; } .box3 { all: revert; }
<body> <div class="wrap"> <div class="box">你好</div> <div class="box box1">你好: initial</div> <div class="box box2">你好: inherit</div> <div class="box box3">你好: revert</div> </div> </body>
1: initial : 還原為初始值
顧名思義這里是將 div身上的所有屬性都重置了, 不管是"背景顏色"還是"字體顏色", 甚至寬高, 所以這里屬于是完全初始化了。
???但是有個大坑, 他會把div原本的display: block
改變成display: inline
, 也就是說all: initial;
將所有屬性置為空了, 而不會根據(jù)標簽屬性進行篩選, 所以這個屬性有點太絕對了要小心使用。
2: inherit: 集成值保留
???依然是顧名思義, 將所有屬性設(shè)置為 "繼承父級", 并且還原自身的屬性, 比如寬高都沒有了但是繼承了字體大小與字體粗細。
???不是所有css屬性的默認值都是'繼承', 比如說position
的默認值就不是集成, 但是position
可以設(shè)置為position: inherit;
, 這就埋下了隱患請看下一條屬性。
3: revert: 還原
???雖然看起來效果與inherit
幾乎一樣, 但是實質(zhì)上有大區(qū)別, 比如如果此時wrap
父元素設(shè)置position: absolute;
, 那么設(shè)置了all: inherit
的元素為position: absolute;
, 設(shè)置了all:revert
的元素是position: static
, 也就是說目標元素單純的還原成最開始的樣式, 剔除掉了后期設(shè)置的屬性, 但保留一些默認的繼承屬性, 這個屬性雖然兼容性超差但最牛!
4: all的優(yōu)先級
.box{ all: revert; background-color: red; }
??? 這里的背景色是可以設(shè)置成功的, 所以all應(yīng)該算一錘子買賣, 只把設(shè)置all屬性
之前的樣式重置。
// 父級 .box { background-color: red !important; } .box1 { all: revert; }
??? 上面是不生效的, 因為all
只能重置優(yōu)先級不如自己選擇器的屬性, 所以需要all: revert!important;
。
六、目標元素樣式 :target
??? 這個屬性讓頁面的url參數(shù)
與dom元素
互動起來
1: 跳轉(zhuǎn)選中
??? 比如當前url
是https://www.xxxxxxxxxxx.com/#target_id
則:
:target { background-color: red; font-size: 200px; }
<div id="target_id"> 你好 </div>
2: 跳轉(zhuǎn)后動畫
??? 我想到的是每次選中元素后讓元素有個動畫效果, 實在太簡單了就不演示了, 說一下這個屬性的雞肋點吧, 比如無法同時傳遞多個id, 或者傳遞class, 并且他讓css屬性與dom結(jié)構(gòu)之間綁定關(guān)系變?nèi)趿舜a不方便維護與閱讀。
七、輸入框的placeholder樣式設(shè)置: placeholder-shown
??? 可以設(shè)置當input
組件中展示placeholder
時的樣式:
input:placeholder-shown { background-color: lightblue; } input { width: 300px; height: 60px; }
<input placeholder="展示我時為藍色" />
輸入內(nèi)容則還原
八、換行展示的藝術(shù): hyphens
??? 當英文單詞必須折行時我們是否需要一個'連字符':
<div class="box"> The auto setting's behavior depends on the language being properly tagged so that the appropriate hyphenation rules can be selected. </div>
.box { border: 1px solid black; width: 200px; height: 100px; }
??? 主角暴風登場
.box { border: 1px solid black; width: 200px; height: 100px; hyphens: auto; }
??? 比較可惜的是無法自由定義'連字符'的樣式, 否則一定有點有趣。
九、滾動的優(yōu)質(zhì)體驗: scroll-snap-type
??? 定義一個滾動時的"臨時停頓點", 這個問題直接看gif動畫比較直接:
??? 簡單來看就是每次慣性滑動都會停留在特定元素所在位置, 有點像滾動的'錨點':
<!DOCTYPE html> <html> <head> <style> .box { width: 200px; height: 150px; border: 1px solid; border-left: 5px solid black; border-right: 5px solid black; margin: 40px; overflow: auto; scroll-snap-type: y mandatory; } .item { border-top: 1px solid red; height: 150px; /* scroll-margin-top:20px; */ scroll-snap-align: start none; } </style> </head> <body> <div class="box"> <div class="item">11111</div> <div class="item">22222</div> <div class="item">33333</div> <div class="item">44444</div> <div class="item">55555</div> <div class="item">66666</div> </div> </body> </html>
???? scroll-snap-type: y mandatory;
設(shè)置了y
軸滾動時盡量停留在'元素點位'上, scroll-snap-align: start none;
目標元素自身的滾動起始方向用來對齊, 也就是告訴瀏覽器滾動后要停留在子元素的哪里。
???? 在子元素身上設(shè)置scroll-margin-top: 20px
可以設(shè)置一定的檢測距離, 并附加回彈效果:
end
???? 這次神奇的css之旅就是這樣, 希望與你一起進步。
(學(xué)習(xí)視頻分享:web前端)