突破css選擇器的侷限,實現一個css地址選擇器?

首先看一個效果,注意地址欄的變化css

theme

而後思考一下,用css如何實現?html

css選擇器的侷限

選擇器是css中的一大特點,用於選擇須要添加樣式的元素。前端

選擇器的種類有不少,好比web

  • 元素選擇器
p {color:gray;}
  • 類選擇器
.box {color:gray;}
  • ID選擇器
#title {color:gray;}
  • 屬性選擇器
[title] {color:gray;}
  • 後代選擇器
h1 span {color:gray;}
  • 相鄰兄弟選擇器
h1 + p {margin-top:50px;}

這裏只列舉了幾種,還有不少,不熟悉的能夠自行搜索查找。瀏覽器

雖說css選擇器有不少種,能夠知足絕大部分的需求,不過有時候仍是會有一些看似合理,實際上比較棘手的問題。佈局

好比說上面提到了相鄰兄弟選擇器,不過只能選擇後面的兄弟節點,卻不能選擇前面的。字體

後代選擇器,能夠選擇子元素,卻無法選擇父元素。spa

用另外一種思惟來突破侷限

上面列出了兩個咱們常見的需求,然而css卻不支持,如何解決呢?設計

不要在這裏提js,這徹底是兩種不一樣的思惟領域code

這裏以實現前置兄弟選擇器爲例

尋找關聯

首先,咱們須要找到和需求有關聯的選擇器,畢竟要以已有的選擇器爲基礎。

這裏說的有關聯指的是相近或者相反,好比子選擇器p>span和後代選擇器p span就是比較相近的

若是要實現鼠標相關的功能,可能就會聯想到:hover:active等選擇器。

這裏要實現前置兄弟選擇器很顯然須要聯繫上已有的相鄰兄弟選擇器+後置選擇器~,都屬於兄弟節點。

解決思路

其實有一種方式是很常見的。

好比有這樣一個佈局,我但願span前面的a(也就是標籤1標籤2)爲紅色字體

<div>
  <a>標籤1</a>
  <a>標籤2</a>
  <span>說明</span>
  <a>標籤3</a>
  <a>標籤4</a>
</div>

咱們用到了後置選擇器~,其實這裏上述規定的位置關係都是以html文檔中的位置爲準的。

咱們能夠手動把這些位置顛倒一下

<div>
  <a>標籤4</a>
  <a>標籤3</a>
  <span>說明</span>
  <a>標籤2</a>
  <a>標籤1</a>
</div>

而後咱們能夠採起不少種方式,讓頁面的順序恢復過來。

好比

a,span{
  float:right
}

這樣在頁面上看到的順序仍是和以前同樣,分別是標籤1標籤2說明標籤3標籤4

而後就能夠直接使用後置選擇器~

span ~ a{
  color:red
}

這樣是否是就作出了在視覺上前置選擇器的效果?不過須要提早把html裏面的結構反過來,經過一些樣式看着順序是正常的便可。

還有一個思路,能夠稱爲逆向思惟吧

佈局和以前同樣

<div>
  <a>標籤1</a>
  <a>標籤2</a>
  <span>說明</span>
  <a>標籤3</a>
  <a>標籤4</a>
</div>

咱們能夠這樣來實現,先把全部的a都設置爲紅色,而後把span後面的a還原,不就達到目的了嗎?

div a{
  color:red;
}
span ~ a{
  color:unset;
}

一樣也實現了這樣的目的。

固然這只是兩個很簡單的例子,詳細的實例能夠參考我以前寫過的文章,更接近實際的需求

css地址選擇器?

這裏能夠明確的說明,css是沒有關於地址的選擇器的。

這裏說的地址是指瀏覽器的地址欄,好比

http://test.com/a

http://test.com/b

或者

http://test.com#a

http://test.com#b

有人可能以爲這是個僞需求,個人地址都變了,都不是同一個頁面了,我在不一樣的頁面分別寫不一樣的css不就好了?

這個思路再有些狀況是是對的,有些狀況下有的問題

好比從http://test.com#ahttp://test.com#b這種狀況下,通常都仍是同一個頁面

而且,如今不少單頁面應用地址欄的改變並無引發瀏覽器頁面的刷新,地址的更變徹底就是前端路由實現的,好比說個人博客

一個需求

其實我最先想到要這種選擇器的時候,是作主題選擇的功能。

好比http://test.comhttp://test.com#light表示正常主題,http://test.com#dark表示黑色主題。

這樣作的一個好處就是能夠很直觀的從地址欄看出主題配色,好比能夠直接以http://test.com#dark進入黑色主題。

相似的想法就是

下面是僞代碼

#light div{
  background:#fff;
  color:#000;
}
#dark div{
  background:#000;
  color:#fff;
}

固然如今跟地址欄半毛錢的關係都沒有。

那麼,這樣實現一個地址選擇器?

思路

按照上面的思路,咱們先考慮跟地址有關聯的選擇器,乍一看,確實找不到一個合適的

後來忽然發現了:target選擇器,這個是用來選擇當前活動的 HTML 錨點的。

官方的示例也都很簡單,簡單來說就是若是當前地址欄爲#new,那麼文檔中idnew的元素就會被選中

下面是w3school的示例

http://www.w3school.com.cn/tiy/t.asp?f=css_sel_target

實現

那麼怎樣實現咱們須要的功能呢?

這裏有一個簡單的佈局

<div>
  <p>演示</p>
</div>

若是想實現http://test.com#dark的功能,那麼文檔中就應該有個iddark的元素能夠選擇到

<div id="dark">
  <p>演示</p>
</div>

加上id後,就能夠實現相似的功能了

/**正常主題**/
p{
  background:#fff;
  color:#000;
}
/**黑色主題**/
#dark:target p{
  background:#000;
  color:#fff;
}

這麼容易?

上面固定了一個,若是有多個,好比紅色主題,綠色主題,黃色主題...不可能全都寫在一個div上吧

<!--錯誤代碼-->
<div id="紅色" id="綠色" id="黃色">
  <p>演示</p>
</div>

這裏就要區分開來了,咱們須要在額外的地方來添加一些id,好比在頁面的最上面

<div id="red"></div>
<div id="green"></div>
<div id="blue"></div>
<div>
  <p>演示</p>
</div>

而後結合兄弟選擇器就能夠實現以下效果

#red:target ~ div p{
  background:red;
}
#green:target ~ div p{
  background:green;
}
#blue:target ~ div p{
  background:blue;
}

這裏是demo

效果如文章開頭所示。

這裏直接作了切換,源碼能夠右鍵直接查看

很簡潔不是嗎,也不須要本地存儲,直接根據地址欄來決定主題配色。

小節

以上主要講解了css的一些侷限性,可是css足夠靈活,有些地方多是設計時候的缺陷,不可避免,可是徹底能夠經過其靈活性達到咱們想要的效果

更先進的css4也將會到來,更多有趣的事情等着咱們來發掘

插一句

還有一個更爲強大的適用場景,就是多語言的適配,能夠根據地址欄直接決定頁面的語言

#zn:target{
  /* 一些邏輯 */
}

#en:target{
  /* 一些邏輯 */
}

#jp:target{
  /* 一些邏輯 */
}

這個後面會專門有一篇文章來說解,敬請期待


若是喜歡個人博客,能夠多多關注一下,謝謝 ~

相關文章
相關標籤/搜索