成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

CSS中的選擇器是什么

本篇內(nèi)容主要講解“CSS中的選擇器是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“CSS中的選擇器是什么”吧!

創(chuàng)新互聯(lián)提供成都網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì),品牌網(wǎng)站設(shè)計(jì),廣告投放平臺(tái)等致力于企業(yè)網(wǎng)站建設(shè)與公司網(wǎng)站制作,10余年的網(wǎng)站開發(fā)和建站經(jīng)驗(yàn),助力企業(yè)信息化建設(shè),成功案例突破數(shù)千家,是您實(shí)現(xiàn)網(wǎng)站建設(shè)的好選擇.

選擇器語法

我們先了解一下選擇器的語法,然后深入了解背后相關(guān)的特性。

簡(jiǎn)單選擇器

  • 星號(hào)—— *

    • 通用選擇器,可以選擇任何的元素

  • 類型選擇器|type selector —— div svg|a

    • 也叫做 type selector, 也就是說它選擇的是元素中的 tagName (標(biāo)簽名) 屬性

    • tagName 也是我們平常最常用的的選擇器

    • 但是因?yàn)?HTML 也是有命名空間的,它主要有三個(gè):HTML、SVGMathML

    • 如果我們想選 SVG 或者 MathML 里面特定的元素,我們就必須要用到單豎線 | ,CSS選擇器里面單豎線是一個(gè)命名空間的分隔符,而HTML 里面命名空間分隔符是 冒號(hào) : 。然后前面說到的命名空間是需要 @namespace 來聲明的,他們是配合使用的,但是這個(gè)命名空間的使用不是很頻繁,它的存在只是為了一個(gè)完備性考慮,HTML 和 SVG當(dāng)中唯一一個(gè)重疊的元素名就只有一個(gè) a

    • 所以我們可以認(rèn)為,類型選擇器就是一個(gè)簡(jiǎn)單的文本字符串即可

  • 類選擇器|c(diǎn)lass selector —— .class-name

    • . 開頭的選擇器就是 class 選擇器,也是最經(jīng)典之一

    • 它會(huì)選擇一個(gè) class,我們也可以用空格做分隔符來制定多個(gè) class 的

    • 這個(gè) .class 只要匹配中其中一個(gè)就可以了

  • ID 選擇器|id selector —— #id

    • # 開頭加上 ID 名選中一個(gè) ID

    • 這個(gè)是嚴(yán)格匹配的

    • ID 里面是可以加減號(hào)或者是其他符號(hào)的

  • 屬性選擇器|attribute selector —— [attr=value]

    • 它包括了 class 屬性選擇器和 id 選擇器

    • 這個(gè)選擇器的完整語法就是 attr=value,等于前面是屬性名,后面是屬性值

    • 這里面的等號(hào)前面可以加 就表示像 class 一樣,可以支持拿空格分隔的值的序列:attr~=value

    • 如果在等號(hào)前面加單豎線,表示這個(gè)屬性以這個(gè)值開頭即可:attr|=value

    • 如果我們對(duì)優(yōu)先級(jí)沒有特殊要求的話,我們理論上是可以用屬性選擇器來代替 class 選擇器和 id 選擇器的

  • 偽類—— :hover

    • : 開頭的,它主要是一些屬性的特殊狀態(tài)

    • 這個(gè)跟我們寫的 HTML 沒有關(guān)系,多半來自于交互和效果

    • 一些偽類選擇器是帶有函數(shù)的偽類選擇器,這些我們都是可以去使用偽類來解決的

  • 偽元素選擇器—— ::before

    • 一般來說是以 :: 雙冒號(hào)開頭的

    • 實(shí)際上是支持使用單冒號(hào)的,但是我們提倡雙冒號(hào)這個(gè)寫法

    • 因?yàn)槲覀兛梢砸谎劬涂闯鲞@個(gè)是偽元素選擇器,和偽類區(qū)分開來

    • 偽元素屬于選中一些原本不存在的元素

    • 如果我們不選擇它們,這個(gè)地方就不存在這個(gè)元素了,選擇后就會(huì)多了一個(gè)元素

復(fù)合選擇器

  • <簡(jiǎn)單選擇器><簡(jiǎn)單選擇器><簡(jiǎn)單選擇器>

  • * 或則 div 必須寫在最前面

首先復(fù)合選擇器是以多個(gè)簡(jiǎn)單選擇器構(gòu)成的,只要把簡(jiǎn)單選擇器挨著寫就變成一個(gè)復(fù)合選擇器了。它的語義就是我們選中的元素必須同時(shí) match 幾個(gè)簡(jiǎn)單選擇器,形成了 “與” 的關(guān)系。

復(fù)雜選擇器

復(fù)合選擇器中間用連接符就可以變成復(fù)雜選擇器了,復(fù)雜選擇器是針對(duì)一個(gè)元素的結(jié)構(gòu)來進(jìn)行選擇的。

  • <復(fù)合選擇器> <復(fù)合選擇器> —— 子孫選擇器,單個(gè)元素必須要有空格左邊的一個(gè)父級(jí)節(jié)點(diǎn)或者祖先節(jié)點(diǎn)

  • <復(fù)合選擇器> “>” <復(fù)合選擇器> —— 父子選擇器,必須是元素直接的上級(jí)父元素

  • <復(fù)合選擇器> “~” <復(fù)合選擇器> —— 鄰接關(guān)系選擇器

  • <復(fù)合選擇器> “+” <復(fù)合選擇器> —— 鄰接關(guān)系選擇器

  • <復(fù)合選擇器> “||” <復(fù)合選擇器> —— 雙豎線是 Selector Level 4 才有的,當(dāng)我們做表格的時(shí)候可以選中每一個(gè)列

選擇器優(yōu)先級(jí)

在之前的 《實(shí)戰(zhàn)中學(xué)習(xí)瀏覽器工作原理》中也接觸過選擇器的優(yōu)先級(jí)的概念了。這里我們深入了解一下選擇器優(yōu)先級(jí)的概念。

簡(jiǎn)單選擇器計(jì)數(shù)

我們從一個(gè)案例出發(fā),選擇器優(yōu)先級(jí)是對(duì)一個(gè)選擇器里面包含的所有簡(jiǎn)單選擇器進(jìn)行計(jì)數(shù)。所以選擇器列表不被視為一個(gè)完整的選擇器(也就是逗號(hào)分隔的選擇器),因?yàn)檫x擇器列表中間是以逗號(hào)分隔開的復(fù)雜選擇器來進(jìn)行簡(jiǎn)單選擇器計(jì)數(shù)的。

例子:#id div.a#id

  • 這個(gè)里面包含了兩個(gè) ID 選擇器,一個(gè)類型選擇器和一個(gè) class 選擇器

  • 根據(jù)一個(gè) specificity 數(shù)組的計(jì)數(shù) [inline-style個(gè)數(shù),ID 選擇器個(gè)數(shù),class 選擇器個(gè)數(shù),tagName 選擇器個(gè)數(shù)]

  • 我們這個(gè)例子就會(huì)得出 specificity = [0, 2, 1, 1]

  • 在選擇器的標(biāo)準(zhǔn)里面,有一個(gè)這樣的描述,我們會(huì)采用一個(gè) N 進(jìn)制來表示選擇器優(yōu)先級(jí)

  • 所以 CSS中的選擇器是什么

  • 我們只需要取一個(gè)大的 N,算出來就是選擇器的優(yōu)先級(jí)了

  • 比如說我們用  N=1000000,那么 S=2000001000001,這個(gè)就是這個(gè)例子中選擇器的 specificity 優(yōu)先級(jí)了

像 IE 的老版本 IE6,因?yàn)闉榱斯?jié)省內(nèi)存 N 取值不夠大,取了一個(gè) 255 為 N 的值,所以就發(fā)生了非常好玩的事情,比如說到值我們 256 個(gè) class 就相當(dāng)于一個(gè) ID。后來我們大部分的瀏覽器都選擇了 65536,基本上就再也沒有發(fā)生過超過額度的事情了。因?yàn)闃?biāo)準(zhǔn)里面只說采用一個(gè)比較大的值就可以,但是我們要考慮內(nèi)存暫用的問題,所以我們會(huì)取一個(gè) 16 進(jìn)制上比較整的數(shù),一般來說都是 256 的整次冪(因?yàn)?256 是剛好是一個(gè)字節(jié))。

CSS 偽類

偽類其實(shí)是一類非常多的內(nèi)容的簡(jiǎn)單選擇器。

鏈接/行為

  • :any-link —— 可以匹配任何的超鏈接

  • :link —— 還沒有訪問過的超鏈接

  • :link :visited —— 匹配所有被訪問過的超鏈接

  • :hover —— 用戶鼠標(biāo)放在元素上之后的狀態(tài),之前是只能對(duì)超鏈接生效,但是現(xiàn)在是可以在很多元素中使用了

  • :active —— 之前也是只對(duì)超鏈接生效的,點(diǎn)擊之后當(dāng)前的鏈接就會(huì)生效

  • :focus —— 就是焦點(diǎn)在這個(gè)元素中的狀態(tài),一般用于 input 標(biāo)簽,其實(shí)任何可以獲得焦點(diǎn)的元素都可以使用

  • :target —— 鏈接到當(dāng)前的目標(biāo),這個(gè)不是給超鏈接用的,是給錨點(diǎn)的 a 標(biāo)簽使用的,就是當(dāng)前的 HASH指向了當(dāng)前的 a 標(biāo)簽的話就會(huì)激活 target 偽類

一旦使用了 :link 或者 :visited 之后,我們就再也無法對(duì)這個(gè)元素的文字顏色之外的屬性進(jìn)行更改。為什么要這樣設(shè)計(jì)呢?因?yàn)橐坏┪覀兪褂昧?layout 相關(guān)的屬性,比如說我們給 :visited 的尺寸加大一點(diǎn),它就會(huì)影響排班。這樣我們就可以通過 JavaScript 的 API 去獲取這個(gè)鏈接是否被訪問過了。但是如果我們能獲得鏈接是否被訪問過了,那么我們就可以知道用戶訪問過那些網(wǎng)站了,這個(gè)對(duì)于瀏覽器的安全性來說是一個(gè)致命打擊。所以這里也提醒一下大家,不要以為做一些表現(xiàn)性的東西于安全沒有任何關(guān)系,其實(shí)安全性是一個(gè)綜合的考量。CSS 它也能造成安全漏洞的。

樹結(jié)構(gòu)

  • :empty —— 這個(gè)元素是否有子元素

  • :nth-child() —— 是父元素的第幾個(gè)兒子(child)

  • :nth-last-child() —— 于 nth-child 一樣,只不過從后往前數(shù)

  • :first-child :last-child :only-child

:nth-child 是一個(gè)非常復(fù)雜的偽類,里面支持一種語法,比如說可以在括號(hào)里面寫奇偶 event 或者 odd,也可以寫 4N+1、3N-1,這個(gè)就會(huì)分別匹配到整數(shù)的形態(tài)。因?yàn)檫@個(gè)是一個(gè)比較復(fù)雜的選擇器,我們就不要在里面寫過于復(fù)雜的表達(dá)式了,只用它來處理一下奇偶,逢3個(gè)多1個(gè),逢4個(gè)多1個(gè)等等這種表達(dá)式。

其實(shí) empty 、 nth-last-child、last-child、only-child 這兩個(gè)選擇器,是破壞了我們之前在 《實(shí)現(xiàn)中學(xué)習(xí)瀏覽器原理》中的說到的 CSS 計(jì)算的時(shí)機(jī)問題。我們可以想象一下,當(dāng)我們?cè)陂_始標(biāo)簽計(jì)算的時(shí)候,肯定不知道它有沒有子標(biāo)簽。empty 影響不是特別大,但是 last-child 的這個(gè)關(guān)系其實(shí)還是影響蠻大的。所以瀏覽在實(shí)現(xiàn)這些的時(shí)候是做了特別處理的,要么就是瀏覽器實(shí)現(xiàn)的不是特別好,要么就是瀏覽器要耗費(fèi)更大的性能來得以實(shí)現(xiàn)。所以建議大家盡量避免大量使用這些。

邏輯型

  • :not 偽類 —— 主流瀏覽器只支持簡(jiǎn)單選擇器的序列(復(fù)合選擇器)我們是沒有辦法在里面寫復(fù)雜選擇器的語法的

  • :where :has —— 在 CSS Level 4 加入了這兩個(gè)非常強(qiáng)大了邏輯型偽類

這里還是像溫馨建議一下大家,不建議大家把選擇器寫的過于復(fù)雜,我們很多時(shí)候都可以多加一點(diǎn) class 去解決的。如果我們的選擇器寫的過于復(fù)雜,某種程度上意味著 HTML 結(jié)構(gòu)寫的不合理。我們不光是為了給瀏覽器工程省麻煩,也不光是為了性能,而是為了我們自身的代碼結(jié)構(gòu)考慮,所以我們不應(yīng)該出現(xiàn)過于復(fù)雜的選擇器。

CSS 偽元素

一共分為 4 種

  • ::before

  • ::after

  • ::first-line

  • ::first-letter

::before::after 是在元素的內(nèi)容的前和后,插入一個(gè)偽元素。一旦應(yīng)用了 before 和 after 的屬性,declaration(聲明)里面就可以寫一個(gè)叫做 content 的屬性(一般元素是沒有辦法寫 content 的屬性的)。content 的屬性就像一個(gè)真正的 DOM 元素一樣,可以去生成盒,可以參與后續(xù)的排版和渲染了。所以我們可以給他聲明 border、background等這樣的屬性。

可以理解為:偽元素向界面上添加了一個(gè)不存在的元素。

::first-line::first-letter 的機(jī)制就不一樣了。這兩個(gè)其實(shí)原本就存在 content 之中。他們顧名思義就是 選中“第一行” 和選中 “第一個(gè)字母”。它們 不是一個(gè)不存在的元素,是把一部分的文本括了起來讓我們可以對(duì)它進(jìn)行一些處理。

before 和 after

在我們概念里,我們可以認(rèn)為帶有 before 偽元素的選擇器,會(huì)給他實(shí)際選中的元素的內(nèi)容前面增加了一個(gè)元素,我們只需要通過他的 content 屬性為它添加文本內(nèi)容即可。(這里我們也可以給偽元素賦予 content: '' 為空的)所以我們可以任何的給 before 和 after 指定 display 屬性,和不同元素一樣比較自由的。

我們?cè)趯?shí)現(xiàn)一些組建的時(shí)候,也會(huì)常常使用這種不污染 DOM 樹,但是能實(shí)際創(chuàng)造視覺效果的方式來給頁面添加一些修飾性的內(nèi)容。

<div>
  <::before/>
  content content content content
  content content content content
  content content content content
  content content content content
  <::after/>
</div>

first-letter 和 first-line

first-letter 相當(dāng)于我們有一個(gè)元素把內(nèi)容里面的第一個(gè)字母給括了起來。這個(gè) first-letter 我們是可以任意聲明各種不同的屬性的,但是我們是無法改變它的 content 的。我們應(yīng)該都看到過報(bào)紙上的第一個(gè)字母會(huì)比較大,然后會(huì)游離出來的效果,這個(gè)在 CSS 里面我們就可以用 ::first-letter的偽元素選擇器了。使用這個(gè)來實(shí)現(xiàn)相比用 JavaScript 來實(shí)現(xiàn)就會(huì)更加穩(wěn)定和代碼更加優(yōu)雅一些。

<div>
  <::first-letter>c</::first-letter>ontent content content content
  content content content content
  content content content content
  content content content content
</div>

first-line 是針對(duì)排版之后的 line,其實(shí)跟我們?cè)创a里面的 first line 沒有任何的關(guān)系的。假如說我們的瀏覽器提供的渲染的寬度不同,first-line 在兩個(gè)環(huán)境里面它最終括住的元素?cái)?shù)量就不一樣多了。所以我們用這個(gè)選擇器的時(shí)候需要去根據(jù)需求的情況使用,很有可能在我們開發(fā)機(jī)器上和用戶的機(jī)器上渲染出來的效果是不一樣的!

<div>
  <::first-line>content content content content content</::first-line>
  content content content content
  content content content content
  content content content content
</div>

這兩個(gè)選擇器其實(shí)可用的屬性也是有區(qū)別的:

first-line 可用屬性

  • font 系列

  • color 系列

  • background 系列

  • word-spacing

  • letter-spacing

  • text-decoration

  • text-transform

  • line-height

first-letter 可用屬性

  • font 系列

  • color 系列

  • background 系列

  • text-decoration

  • text-transform

  • letter-spacing

  • word-spacing

  • line-height

  • float

  • vertical-align

  • 盒模型系列:margin, padding, border

小練習(xí)

編寫一個(gè) match 函數(shù)。它接受兩個(gè)參數(shù),第一個(gè)參數(shù)是一個(gè)選擇器字符串性質(zhì),第二個(gè)是一個(gè) HTML 元素。這個(gè)元素你可以認(rèn)為它一定會(huì)在一棵 DOM 樹里面。通過選擇器和 DOM 元素來判斷,當(dāng)前的元素是否能夠匹配到我們的選擇器。(不能使用任何內(nèi)置的瀏覽器的函數(shù),僅通過 DOM 的 parent 和 children 這些 API,來判斷一個(gè)元素是否能夠跟一個(gè)選擇器相匹配。)以下是一個(gè)調(diào)用的例子。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Match Example —— by 三鉆</title>
  </head>
  <body>
    <div>
      <b>
        <div class="class classA" id="id">content</div>
      </b>
    </div>
  </body>
  <script language="javascript">
    /**
     * 匹配選擇器
     */
    function matchSelectors(selector, element) {
      // 先匹配當(dāng)前元素是否匹配
      let tagSelector = selector.match(/^[\w]+/gm);
      let idSelectors = selector.match(/(?<=#)([\w\d\-\_]+)/gm);
      let classSelectors = selector.match(/(?<=\.)([\w\d\-\_]+)/gm);

      /**
       * 實(shí)現(xiàn)復(fù)合選擇器,實(shí)現(xiàn)支持空格的 Class 選擇器
       * --------------------------------
       */
      // 檢查 tag name 是否匹配
      if (tagSelector !== null) {
        if (element.tagName.toLowerCase() !== tagSelector[0]) return false;
      }
      // 檢測(cè) id 是否匹配
      if (idSelectors !== null) {
        let attr = element.attributes['id'].value;
        if (attr) {
          for (let selector of idSelectors) {
            if (attr.split(' ').indexOf(selector) === -1) return false;
          }
        }
      }
      // 檢測(cè) class 是否匹配
      if (classSelectors !== null) {
        let attr = element.attributes['class'].value;
        if (attr) {
          for (let selector of classSelectors) {
            if (attr.split(' ').indexOf(selector) === -1) return false;
          }
        }
      }

      return true;
    }

    /**
     * 匹配元素
     */
    function match(selector, element) {
      if (!selector || !element.attributes) return false;

      let selectors = selector.split(' ').reverse();

      if (!matchSelectors(selectors[0], element)) return false;

      let curElement = element;
      let matched = 1;

      // 遞歸尋找父級(jí)元素匹配
      while (curElement.parentElement !== null && matched < selectors.length) {
        curElement = curElement.parentElement;
        if (matchSelectors(selectors[matched], curElement)) matched++;
      }

      // 所有選擇器匹配上為 匹配成功,否則是失敗
      if (matched !== selectors.length) return false;

      return true;
    }

    let matchResult = match('div #id.class', document.getElementById('id'));
    console.log('Match example by 三鉆');
    console.log('matchResult', matchResult);
  </script>
</html>

到此,相信大家對(duì)“CSS中的選擇器是什么”有了更深的了解,不妨來實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

標(biāo)題名稱:CSS中的選擇器是什么
分享地址:http://jinyejixie.com/article44/igogee.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站建設(shè)、全網(wǎng)營(yíng)銷推廣、網(wǎng)站排名、做網(wǎng)站、網(wǎng)站設(shè)計(jì)、域名注冊(cè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設(shè)
南郑县| 安丘市| 诸暨市| 海林市| 泽州县| 平罗县| 厦门市| 科尔| 元阳县| 泾阳县| 宁晋县| 大厂| 宾阳县| 山东省| 灵寿县| 当阳市| 永顺县| 葫芦岛市| 贵阳市| 云梦县| 蓝田县| 当阳市| 大余县| 通化市| 三穗县| 宜兰市| 江陵县| 吴忠市| 土默特左旗| 青川县| 南京市| 盈江县| 关岭| 乌鲁木齐市| 阿巴嘎旗| 高密市| 巴青县| 韩城市| 萨嘎县| 富宁县| 英吉沙县|