前言
凡是可以用 JavaScript 來寫的應用,最終都會用 JavaScript 來寫。——Atwood定律
雖然萬物都可以是JavaScript,但某種程度css的運行效率會比JavaScript高,所以筆者認為:能用CSS實現的就不用麻煩JavaScript。
兩種語言都有不同的用途隨著瀏覽器版本特性和屬性的增加,CSS正成為一種功能強大的語言,能夠處理我們以前依賴JavaScript實現的功能。
平滑滾動
曾經有一段時間,我們不得不依靠JavaScript的window.scrollY
來實現來執行此操作,如果想平滑滾動還要依賴定時器增加一個動畫。 隨著scroll-behavior
屬性的新增,我們可以使用一行CSS代碼來處理網站上的平滑滾動!瀏覽器支持約為75%,兼容性還是挺不錯的。
html {
scroll-behavior: smooth;
}
滾動捕抓
幻燈片、圖片庫這些也是前端高頻使用功能,上一代CSS能力有限,我們不得不依賴JavaScript來完成這功能。現在只要幾行代碼就可以實現此功能。
從某種意義上說,它與Flexbox或CSS Grid
的工作原理類似,即您需要一個容器元素,在該容器元素上設置scrolln-snap-type
和多個為其設置了scroll-snap-align
的子元素,如下所示:
<main class=”parent”>
<section class=”child”></section>
<section class=”child”></section>
<section class=”child”></section>
</main>
.parent {
scroll-snap-type: x mandatory;
}
.child {
scroll-snap-align: start;
}
CSS動畫
曾經某個時期,大多數開發者使用 JavaScript(或者jQuery) 給瀏覽器中的元素添加動畫。讓這個淡化,讓那個擴大,很簡單。隨著互動的項目越來越復雜,移動設備的大量增加,表現性能變得越來越重要。Flash 被拋棄,有天賦的動畫開發者使用 HTML5 去實現過去從未實現的效果。他們需要更好的工具去開發復雜的動畫序列并獲得最好的性能。JavaScript(或者jQuery) 并不能夠做到。瀏覽器日漸成熟的同時也開始提供了一些解決方案。最被廣泛接受的方案是使用 CSS 動畫。
表單驗證
html5 豐富了表單元素,提供了類似 required , email , tel 等表單元素屬性。同樣的,我們可以利用 :valid 和 :invalid 來做針對html5表單屬性的校驗。
- :required 偽類指定具有required 屬性的表單元素
- :valid 偽類指定一個通過匹配正確的所要求的表單元素
- :invalid 偽類指定一個不匹配指定要求的表單元素
利用 CSS 的 content 屬性 attr 抓取資料
想必大家都想到了偽元素 after ,但是文字怎么獲得呢,又不能用 JavaScript 。
CSS 的偽元素是個很強大的東西,我們可以利用他做很多運用,通常為了做一些效果, content:" " 多半會留空,但其實可以在里面寫上 attr 抓資料哦!
<div data-msg="這里是獲取content的內容">
hover
</div>
div{
width:100px;
border:1px solid red;
position:relative;
}
div:hover:after{
content:attr(data-msg);
position:absolute;
font-size: 12px;
width:200%;
line-height:30px;
text-align:center;
left:0;
top:25px;
border:1px solid green;
}
鼠標懸浮時顯示
鼠標懸浮的場景十分常見,例如導航的菜單:
一般要把隱藏的東西如菜單作為hover目標的子元素或者相鄰元素,才方便用css控制,例如上面的菜單,是把menu當作導航的一個相鄰元素:
<!--menu為相鄰的li-->
<li class="user">用戶</li>
<li class="menu">
<ul>
<li>賬戶設置</li>
<li>登出</li>
</ul>
</li>
menu在正常態下是隱藏的:
.menu{
display: none;
}
而當導航hover時顯示:
/*使用相鄰選擇器和hover*/
.user:hover + .menu{
display: list-item;
}
注意這里使用了一個相鄰選擇器,這也是上面說的為什么要寫成相鄰的元素。menu的位置可以用absolute定位。
同時menu自已本身hover的時候也要顯示,否則鼠標一離開導航的時候,菜單就消失了:
.menu:hover{
display: list-item;
}
這里會有一個小問題,即menu和導航需要挨著一起,否則中間有空隙的話,上面添加的菜單hover就不能發揮作用了,但是實際情況下從美觀的角度,兩者是要有點距離的。這個其實也好解決,只要在menu上面再畫一個透明的區域就好了,如下藍色的方塊:
可以用before/after偽類用absoute定位實現:
ul.menu:before{
content: "";
position: absolute;
left: 0;
top: -20px;
width: 100%;
height: 20px;
/*background-color: rgba(0,0,0,0.2);*/
}
如果我既寫了css的hover,又監聽了mouse事件,用mouse控制顯示隱藏,雙重效果會有什么情況發生,如果按正常套路,在mouse事件里面hover的時候,添加了一個display: block的style,會覆蓋掉CSS的設置。也就是說,只要hover一次,css的代碼就不管用了,因為內聯樣式的優先級會高于外鏈的。但是實際情況下會有意外發生,那就是在移動端iphone上面,觸摸會觸發CSS的hover,并且這個的觸發會很高概率地先于touchstart事件,在這個事件里面會判斷當前是顯示還是隱藏的狀態,由于css的hover發揮了作用,所以判斷為顯示,然后又把它隱藏了。也就是說,點一次不出來,要點兩次。所以最好別兩個同時寫。
第二種場景,使用子元素,這個更簡單。把hover的目標和隱藏的對象當作同一個父容器的子元素,然后hover寫在這個父容器上面就可以了,不用像上面那樣,隱藏元素也要寫個hover:
.marker-container .detail-info{
display: none
}
.marker-container:hover .detail-info{
display: block
}
最后
這里展示也只是一些常用的功能,其實還有很多可以通過CSS實現的功能,有興趣的同學繼續研究一下更多不依賴JavaScript完成的CSS功能。