內容過濾是一個在Web上常見的一個功能,特別是在電商網站,為了讓使用者過濾內容,僅顯示符合自己的要求的內容。截個圖來說,能更好的說明這樣的功能,比如淘寶網:
如上圖所示,使用者想購買一件裙子,在整個產品列表中,顯示的產品數量太多了。顧客不知道如何選擇自己所需要的裙子。在頂部提供了一個分類,顧客選擇需要的選項,產品中就會過濾掉不合格產品。上圖選擇了”氣質優雅“的裙子。當然還可以選擇更多的條件。這裡就不我多說了。
話說回來,以前實現這樣一個效果都需要藉助於JavaScript(或者基於jQuery外掛程式)來做。比如CodyHouse的內容過濾樣本。但對於一枚不懂JavaScript的同學來說(不懂不是理由),要實作類別似的一個功能,的確是一件難事(偶有切身體會,欲哭無淚,誰叫當初沒好好讀書)。
所幸的事,如今天偶也可以不藉助JavaScript來實現。也就是純CSS來實現一個功能簡單一點的內容過濾器,不是難事。這也是今天要與大家一起分享的。
先來看一個樣本
先來看一個簡單的樣本,頁面載入時,會有女裝、男裝和童裝一起出現,當你做下面的操作時,有意想不到的效果:
當你點擊”女裝“按鈕時,”男裝“和”童裝“都會被過濾掉
當你點擊”男裝“按鈕時,”女裝“和”童裝“都會被過濾掉
當你點擊”童裝“按鈕時,”女裝“和”男裝“都會被過濾掉
當然這個案例的功能沒有淘寶網的那麼NB,但好獃也是完成了一個類似內容過濾的功能。
實現原理
實現這個功能的原理其實並不太複雜,只是大家平時並未關注過。我歸納起來就是兩個方面:
強大的選取器
實現這個功能,主要依賴於強大的CSS選取器中的通用兄弟選取器(E~F)和偽類別選取器:checked。當某個選項按鈕選中時,其他類的內容隱藏起來:
input[type="radio"]{
&[id="men"]:checked {
~ .women,
~ .children{
....
}
}
}
要通過上面樣式來控制對應的.women和.children元素,必須保證元素與input元素是兄弟元素。這也是下面要說的第二個關鍵之處。
良好、匹配的結構
僅利用CSS製作這個功能,需要有嚴謹的結構,因為結構的錯亂直接會影響到需要的效果。這也是其中不足之處。其中之一就是藉助選項按鈕”radio“和label匹配。為了外觀的好看,不想顯示<input type="radio">,需要通過label的for屬性來控制選中的”radio“。所以input的id值要和label的for值匹配。另外所有的input的name值一樣,告訴瀏覽器,他們是屬於一組的。如:
<input type="radio" id="men" name="clothing" />
<label for="men">男裝</label>
<input type="radio" id="women" name="clothing"/>
<label for="women">女裝</label>
<input type="radio" id="children" name="clothing"/>
<label for="children">童裝</label>
<input type="radio" id="reset" name="clothing"/>
<label for="reset">重設</label>
實現步驟
瞭解實現原理之後,要完成文章開頭樣本的效果就簡單的多了。
HTML
HTML結構其實非常簡單,只需要注意input和label的匹配以及將要過濾內容元素與其是兄弟元素。比如此例,內容元素主要有三類:男裝.men、女裝.women和童裝.children。
<div class="container">
<!-- 必須保證input和label匹配 -->
<input type="radio" id="men" name="clothing " />
<label for="men">男裝</label>
<input type="radio" id="women" name="clothing "/>
<label for="women">女裝</label>
<input type="radio" id="children" name="clothing "/>
<label for="children">童裝</label>
<input type="radio" id="reset" name="clothing "/>
<label for="reset">重設</label>
<!-- 要被過濾的內容元素需要與input元素是兄弟元素 -->
<div class="tile men">
<img src="" alt="">
</div>
<div class="tile women">
<img src="" alt="">
</div>
<div class="tile children">
<img src="" alt="">
</div>
<!-- 此處省略N個.men、.women和.children元素 -->
</div>
SCSS
明白原理,就簡單多了,首先來看整體的代碼:
body{
margin:0;
text-align:center;
font-family: Verdana;
background:#f5f5f5;
}
h1 {
text-align:center;
}
.container {
width:90%;
margin:0 auto;
}
input[type="radio"] {
display:none;
}
label {
width:23%;
float:left;
text-align:center;
background:#ffffff;
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
color:#222222;
padding:0.5%;
margin:0.5%;
margin-bottom:30px;
cursor:pointer;
}
input[type="radio"]{
&[id="men"]:checked {
* label {
background:#6666ff;
}
~ .women,
~ .children {
width:0;
height:0;
padding:0;
margin:0;
opacity:0;
}
}
&[id="women"]:checked {
* label {
background:#ff4466;
}
~ .men,
~ .children {
width:0;
height:0;
padding:0;
margin:0;
opacity:0;
}
}
&[id="children"]:checked {
* label {
background:#66dd99;
}
~ .men,
~ .women {
width:0;
height:0;
padding:0;
margin:0;
opacity:0;
}
}
}
.tile {
width:23%;
float:left;
transition:all 1s;
margin:0.5%;
padding:0.5%;
background:#6666ff;
img {
width: 100%;
}
}
簡單的解析一下這個樣式代碼。
為了頁面好看,首先把<input>隱藏掉:
input[type="radio"] {
display:none;
}
我們通過label的for屬性來控制radio有沒有選中。美化一下label樣式:
label {
width:23%;
float:left;
text-align:center;
background:#ffffff;
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
color:#222222;
padding:0.5%;
margin:0.5%;
margin-bottom:30px;
cursor:pointer;
}
接下來樣式代碼也是最關鍵的一部分,當input選中之後label的樣式:
input[type="radio"]{
&[id="men"]:checked {
+ label {
background:#6666ff;
}
}
...
}
上面的代碼錶示的是<input type="radio" id="men">選擇中:checked時,其相鄰的label改變背景顏色。
根據前面的原理介紹,可以得知,當我們選擇了”男裝“,那麼”女裝“和”童裝“就需要隱藏,在這裡通過假像來隱藏,也就是input[type="radio"][id="men"]選中,其相通兄弟元素.women和.children隱藏掉:
input[type="radio"]{
&[id="men"]:checked {
...
~ .women,
~ .children {
width:0;
height:0;
padding:0;
margin:0;
opacity:0;
}
}
}
其他兩個選項也是類似的,就不在做過多的闡述。
美化的樣式,這裡就不說了,大家都懂的。
通過這個過程下來,你就能看到前面DEMO展示的效果了。
總結
本文主要介紹了如何依賴於CSS的屬性選取器、通用相鄰兄弟選取器和偽類別選取器來實現一個簡單的內容過濾的功能。在整個執行個體當中,要把握的是嚴謹的HTML結構,因為相鄰兄弟選取器對於結構的依賴程度非常的強。也就是說結構修改之後,你的選取器和樣式都要做一定的修改。
通篇下來,是不是覺得非常的簡單。如果你感興趣的話,可以藉助這個案例的思路,通過”複選框“按鈕來實現多項內容過濾的效果。也就是符合多個條件的內容顯示,不符合的隱藏。試試唄,你一定行。