神奇的選擇器 :focus-within

来源:https://www.cnblogs.com/coco1s/archive/2018/08/02/9406413.html
-Advertisement-
Play Games

CSS 的偽類選擇器和偽元素選擇器,讓 CSS 有了更為強大的功能。 偽類大家聽的多了,偽元素可能聽到的不是那麼頻繁,其實 CSS 對這兩個是有區分的。 有個錯誤有必要每次講到偽類都提一下,有時你會發現偽類元素使用了兩個冒號 (::) 而不是一個冒號 (:),這是 CSS3 規範中的一部分要求,目的 ...


CSS 的偽類選擇器和偽元素選擇器,讓 CSS 有了更為強大的功能。

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

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

通常而言,

#id:after{
 ...
}

#id::after{
...
}

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

當然,也有例外,對於 CSS2 中已經有的偽元素,例如 :before,單冒號和雙冒號的寫法 ::before 作用是一樣的。

所以,如果你的網站只需要相容 webkit、firefox、opera 等瀏覽器或者是移動端頁面,建議對於偽元素採用雙冒號的寫法,如果不得不相容低版本 IE 瀏覽器,還是用 CSS2 的單冒號寫法比較安全。

 

偽類選擇器 :focus-within

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

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

這也就意味著,它或它的後代獲得焦點,都可以觸發 :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 {
        ....
    }
}

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 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%;

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

        &:placeholder-shown {
            ...
        }
    }

    &: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 訂閱收藏。

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

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

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 原文鏈接: "超詳細Hexo+Github博客搭建小白教程" 去年9月的時候開始搭建了第一個自己的獨立博客,到現在也稍微像模像樣了。很多小伙伴應該也想過搭建一個自己的博客,網上也有一堆詳細教程。我在此稍稍總結一下具體的搭建步驟,另外網上很少有修改博客源碼的個性化教程,我就稍稍分享一下我的一些修改經驗 ...
  • 最近遇到後端返回數據,需要前端進行篩選展示的一個需求 這個是在react中寫的方法未命名文件 // 輸入框變化時,觸發onchange事件,進行數據篩選 changeZons = (e) = { const { zonesList } = this.state; const searchData = ...
  • 看了很多關於TypeScript的文章,總體說來沒有很好的,一個系統的學習TypeScript的資源。 接下來,我將給大家帶來TypeScript的系列,讓你和我一樣,一步一步的學習TypeScript,並且學以致用。 什麼是TypeScript呢 在TypeScript的官方網站上面有這樣的描述:... ...
  • 代碼可以在 https://pan.baidu.com/s/1uN120-18hvAzELpJCQfbXA 處下載 開始,創建一個paiziDm 的分支 git checkout -b paiziDm ,我們再寫代碼 下麵來 分析思路 就是模擬點擊 換徽章 的過程,如果沒有當前房間的徽章,則不戴。 ...
  • 最近開發小程式,為瞭解耦數據 寫了一個wenaox的庫,一開始放在libs里使用相對路徑引入,覺得很辛苦, 後面發現小程式的npm已經進入beta版本,於是下載了beta開發工具,構建後就可以直接import引入 很爽 有需要可以下載用一下 [Wenaox][wenaox url] [![NPM v ...
  • Javascript是一種基於對象的語言,你遇到的所有東西幾乎都是對象。但是,它又不是一種真正的面向對象編程(OOP)語言,因為它的語法中沒有Class。(不過,ES6引入了Class這個概念,作為對象的模板。通過class關鍵字,可以定義類。ES6入門:http://es6.ruanyifeng. ...
  • 1、代碼: <!DOCTYPE html><html><head> <meta charset="utf-8"> <title>JS過渡和變形效果演示</title> <style type="text/css"> *{ margin: 0; padding: 0; } .container{ wi ...
  • 1:children及find方法都用是用來獲得element的子elements的,兩者都不會返回 text node,就像大多數的jQuery方法一樣。 2:children方法獲得的僅僅是元素一下級的子元素,即:immediate children。 3:find方法獲得所有下級元素,即:de ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...