神奇的選擇器 :focus-within,子控制父

轉自神奇的選擇器 :focus-within

CSS 的僞類選擇器僞元素選擇器,讓 CSS 有了更爲強大的功能。css

僞類你們聽的多了,僞元素可能聽到的不是那麼頻繁,其實 CSS 對這兩個是有區分的。html

有個錯誤有必要每次講到僞類都提一下,有時你會發現僞類元素使用了兩個冒號 (::) 而不是一個冒號 (:),這是 CSS3 規範中的一部分要求,目的是爲了區分僞類和僞元素,大多數瀏覽器都支持下面這兩種表示方式。git

一般而言,github

web

#id:after{  ... } 複製代碼#id::after{ ... } 複製代碼複製代碼

符合標準而言,單冒號(:)用於 CSS3 僞類,雙冒號(::)用於 CSS3 僞元素。瀏覽器

固然,也有例外,對於 CSS2 中已經有的僞元素,例如 :before,單冒號和雙冒號的寫法 ::before 做用是同樣的。安全

因此,若是你的網站只須要兼容 webkit、firefox、opera 等瀏覽器或者是移動端頁面,建議對於僞元素採用雙冒號的寫法,若是不得不兼容低版本 IE 瀏覽器,仍是用 CSS2 的單冒號寫法比較安全。post

僞類選擇器 :focus-within

言歸正傳,今天要說的就是:focus-within 僞類選擇器。網站

它表示一個元素得到焦點,或,該元素的後代元素得到焦點。劃重點,它或它的後代得到焦點spa

這也就意味着,它或它的後代得到焦點,均可以觸發 :focus-within

:focus-within 的冒泡性

這個屬性有點相似 Javascript 的事件冒泡,從可獲焦元素開始一直冒泡到根元素 html,均可以接收觸發 :focus-within 事件,相似下面這個簡單的例子這樣:

<div class="g-father">
    <div class="g-children">
        <input type="button" value="Button">
    </div>
</div>
複製代碼複製代碼

html, body, .g-father, .g-children { padding: 30px; border:1px solid #999; }

input { ... &:focus { background: #00bcd4; } }

複製代碼html:focus-within { background: #e91e63; } body:focus-within { background: #ff5722; } .g-father:focus-within { background: #ffeb3b; } .g-children:focus-within { background: #4caf50; } 複製代碼複製代碼

就是這樣:

focuswithinmaopao

CodePen Demo -- :focus-within 冒泡觸發

這個選擇器的存在,讓 CSS 有了進一步的讓元素持久停留在一種新狀態的的能力。

下面幾個例子,看看 :focus-within 能夠提供什麼能力,作些什麼事情。

感應用戶聚焦區域

它或它的後代得到焦點,這一點使得讓感知獲焦區域變得更大,因此,最常規的用法就是使用 :focus-within 感應用戶操做聚焦區域,高亮提醒。

下面的效果沒有任何 JS 代碼:

cssfocuswithinpesudo

這裏是什麼意思呢?:focus-within 作了什麼呢?

  • 咱們無須去給獲焦的元素設置 :focus 僞類,而是能夠給須要的父元素設置,這樣當元素獲焦時,我能夠一併控制它的父元素的樣式

核心思想用 CSS 代碼表達出來大概是這樣:

<div class="g-container">
    <div class="g-username">
        <input type="text" placeholder="user name" class="g_input" >
    </div>
    <div class="g-username">
        <input type="text" placeholder="code" class="g_input" >
    </div>
</div>
複製代碼複製代碼

.g-container:focus-within { ...
input {
    ....
}
複製代碼
複製代碼input { .... } 複製代碼} 複製代碼複製代碼

DEMO -- CSS focus-within INPUT

運用上面思想,咱們能夠把效果作的更炫一點點,在某些場景製做一些加強用戶體驗的效果:

purecssfocus

DEMO -- PURE CSS FOCUS By :focus-within

TAB導航切換

在以前的一篇文章裏,介紹了兩種純 CSS 實現的 TAB 導航欄切換方法:

純CSS的導航欄Tab切換方案

如今又多了一種方式,利用了 :focus-within 能夠在父節點獲取元素得到焦點的特性,實現的TAB導航切換:

focuswithintab

DEMO -- focus-within switch tab

主要的思路就是經過獲焦態來控制其餘選擇器,以及最重要的是利用了父級的 :not(:focus-within) 來設置默認樣式:

.nav-box:not(:focus-within) { // 默認樣式 }

.nav-A:focus-within ~ .content-box .content-A { display: block; }

複製代碼.nav-B:focus-within ~ .content-box .content-B { display: block; } 複製代碼複製代碼

配合 :placeholder-shown 僞類實現表單效果

:focus-within 一我的能力有限,一般也會配合其餘僞類實現一些不錯的效果。這裏要再簡單介紹的是另一個有意思的僞類 :placeholder-shown

:placeholder-shown:The :placeholder-shown CSS pseudo-class represents any <input> or <textarea> element that is currently displaying placeholder text.

另外,劃重點,這個僞類是仍處於實驗室的方案。也就是未歸入標準,固然咱們的目的是探尋有意思的 CSS 。

意思大概就是,當 input 類型標籤使用了 placeholder 屬性有了默認佔位的文字,會觸發此僞類樣式。配合:not()僞類,能夠再改變當默認文字消失後的樣式,再配合本文的主角,咱們能夠實現表單的一系列效果。

CSS 代碼大概呈現成這樣:

.g-container { width: 500px; height: 60px;
input {
    height: 100%;
    width: 100%;

    &amp;:not(:placeholder-shown) {
        ...
    }

    &amp;:placeholder-shown {
        ...
    }
}

&amp;:focus-within {
    ...
}
複製代碼
複製代碼input { height: 100%; width: 100%; &amp;:not(:placeholder-shown) { ... } &amp;:placeholder-shown { ... } } &amp;:focus-within { ... } 複製代碼} 複製代碼複製代碼

實際效果以下:

placeholder

能夠看到,上面的效果沒有用到任何 JS,能夠實現:

  1. 整個 input(包括父元素所在區域)獲焦與非獲焦樣式控制
  2. placeholder 屬性設置的文字出現與消失後樣式控制

CodePen Demo -- :placeholder-shown && :focus-within

實現離屏導航

這個是其餘不少文章都有提到過的一個功能,利用 focus-within 便捷的實現離屏導航,能夠說將這個屬性的功能發揮的淋漓盡致,這裏我直接貼一個 codepen 上 Dannie Vinther 對這個效果的實現方案:

offscreennav

CodePen Demo -- Off-screen nav with :focus-within [PURE CSS]

實現掘金登陸動效切換

juejin.im是我很喜歡的一個博客網站,它的登陸有一個小彩蛋,最上面的熊貓在你輸入賬號密碼的時候會有不一樣的狀態,效果以下:

juejin

利用本文所講的 focus-within ,能夠不借助任何 Javascript,實現這個動效:

juejinfocuswithin

感興趣的能夠戳這裏看看完整的Demo代碼:

CodePen Demo -- 掘金登陸效果純CSS實現

兼容性

好了,例子舉例的也差很少了,下面到了殺人誅心的兼容性時刻,按照慣例,這種屬性大機率是一片紅色,看看 CANIUSE,截圖日期(2018/08/02),其實也還不算特別慘淡。

image

最後

感謝耐心讀完。本文只是拋磚引玉,期待發掘 focus-within 更多有意義的用法。

更多精彩 CSS 技術文章彙總在個人 Github -- iCSS ,持續更新,歡迎點個 star 訂閱收藏。

好了,本文到此結束,但願對你有幫助 :)

若是還有什麼疑問或者建議,能夠多多交流,原創文章,文筆有限,才疏學淺,文中如有不正之處,萬望告知。

相關文章
相關標籤/搜索