純CSS實現網站經常使用的五角星評分和分數展現交互效果

最近作的一個項目涉及到評分和展現分數的模塊,UI設計師也給了幾個切好的圖片,實現五角星評分方式不少,本質愛折騰的精神和對性能追求以及便於維護的考慮,蒐集和嘗試了不少方式,最終採用了純css驅動的實現方式完成評分和展現分數的功能,沒有js,也就意味着沒判斷邏輯,代碼出錯的概率更少,也更便於維護,在此,把這個功能的實現的過程記錄和分享一下,一塊兒學習交流。css

原文收錄在個人 GitHub博客 (https://github.com/jawil/blog) ,喜歡的能夠關注最新動態,你們一塊兒多交流學習,共同進步。html

五角星的實現

1.圖片或者字體圖標

不極致追求性能的話,直接利用設計師給的png或者jpg啥的,或者直接轉成base64.前端

2:利用Fontawesome 圖標庫,其實只是一種矢量字體。

HTML:vue

<div class="icon"></div>

CSS:css3

@import url(http://netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css);

.icon:before {
    content: '\f005';
    font-family: FontAwesome;
}

在線預覽地址git

3.利用css3描繪拼湊一個五角星。

基本原理:利用transparent的透明不可見和transform轉換拼接一個正五角星。github

HTML:bootstrap

<div class="star-five"></div>

CSS:後端

.star-five{
width: 0;
height: 0;
color: red;
margin: 50px 0;
position: relative;
display: block;
border-left: 100px solid transparent;
border-right: 100px solid transparent;
border-bottom: 70px solid red;
transform:rotate(35deg);
}

.star-five:before{
width: 0;
height: 0;
border-left: 30px solid transparent;
border-right: 30px solid transparent;
border-bottom: 80px solid red;
position: absolute;
top: -45px;
left: -65px;
color: white;
display: block;
content: "";
transform:rotate(-35deg);
}
.star-five:after{
width: 0;
height: 0;
display: block;
position: absolute;
color: red;
top: 3px;
left: -105px;
border-left: 100px solid transparent;
border-right: 100px solid transparent;
border-bottom: 70px solid red;
content: "";
transform:rotate(-70deg);
}

在線預覽地址前端工程師

不建議使用這種,由於選擇以後改變顏色狀態比較麻煩,改起來很不方便,不如前面幾種方便好維護。

4.直接使用五角星符號

★?

簡單粗暴,容易控制,品相協調,下面實現方式以★爲準。




關於CSS的一些選擇器

不用js來控制評分,固然不能錯過強大的css選擇器,這裏就先介紹一下關於實現這個功能要用到的一些css選擇器。

在介紹css強大的選擇器以前,先普及一下「CSS radio/checkbox單複選框元素顯隱技術」,又稱「checkbox hack技術」。

1.checkbox hack技術

咱們使用CSS一些特殊的選擇器,而後配合單選框以及複選框自帶的一些特性,能夠實現元素的顯示隱藏效果。而後經過一
些簡單的擴展,咱們能夠不使用任何JavaScript代碼實現相似:自定義的單複選框,「更多」展開與收起效果,選項卡切換
效果,或是多級下拉列表效果等等。

相信不少前端開發人員都會遇到boss讓修改checkbox和radio樣式,畢竟自帶的樣式太醜了。後來咱們發現修改自帶樣式
並非那麼容易,最後直接使出殺手鐗——點擊以後替換圖片。
今天教你們一種方法,不用替換圖片,隨意修改樣式。仍是先看效果圖:

`先講一下原理:兩個關鍵東東,一是僞類選擇器:checked,表示對應控件元素(單選框或是複選框)選中時的樣式;二就是加號+ 相鄰兄弟選擇器,這個符號表示選擇後面的兄弟節點。因而,二者配合,就能夠輕鬆自如控制後面元素的顯示或者隱藏,或是其餘樣式了。
而如何讓單複選框選中和不選中了,那就是label標籤了哈,for屬性錨定對應的單選框或是複選框,而後點擊這裏的label標籤元素的時候,對應的單複選框就會選中或是取消選中。而後,就有上面的效果啦!`

這裏只給一個radio單選框的代碼,僅供參考:

HTML:

<div class="radio-beauty-container">
    <label>
        <span class="radio-name">前端工程師</span>
        <input type="radio" name="radioName" id="radioName1" hidden/>
        <label for="radioName1" class="radio-beauty"></label>
    </label>
    <label>
        <span class="radio-name">後端工程師</span>
        <input type="radio" name="radioName" id="radioName2" hidden/>
        <label for="radioName2" class="radio-beauty"></label>
    </label>
    <label>
        <span class="radio-name">全棧工程師</span>
        <input type="radio" name="radioName" id="radioName3" hidden/>
        <label for="radioName3" class="radio-beauty"></label>
    </label>
</div>

SCSS:

.radio-beauty-container {
    font-size: 0;
    $bgc: green;
    %common {
        padding: 2px;
        background-color: $bgc;
        background-clip: content-box;
    }
    .radio-name {
        vertical-align: middle;
        font-size: 16px;
    }
    .radio-beauty {
        width: 18px;
        height: 18px;
        box-sizing: border-box;
        display: inline-block;
        border: 1px solid $bgc;
        vertical-align: middle;
        margin: 0 15px 0 3px;
        border-radius: 50%;
        &:hover {
            box-shadow: 0 0 7px $bgc;
            @extend %common;
        }
    }
    input[type="radio"]:checked+.radio-beauty {
        @extend %common;
    }
}

美化radio單選框在線預覽地址:點擊我呀
美化checkbox複選框在線預覽地址:點擊我呀

更多關於這方面的介紹和例子能夠參看張鑫旭大神的這篇文章:CSS radio/checkbox單複選框元素顯隱技術

2.CSS一些選擇器

HTML:

<div class="wrapper">
  <p class="test1">1</p>
  <p class="test2">2</p>
  <p class="test3">3</p>
  <p class="test4">4</p>
  <p class="test5">5</p>
</div>

CSS:

p{
  width:20px;
  line-height:20px;
  border:1px solid gray;
  text-align:center;
  font-weight: 700;
}
E + F: 相鄰兄弟選擇器 選擇匹配F的元素,且該元素爲所匹配E元素後面相鄰的位置。
.test1+p{
  background-color:green;
}

E > F:子包含選擇器 選擇匹配F的元素,且該元素爲所匹配E元素的子元素。
.wrapper>p{
  background-color:green;
}

E ~ F: 選擇後面的兄弟節點們
.test2~p{
  background-color:green;
}

E::after,E::before: 僞元素選擇器 在匹配E的元素後面(前面)插入內容
.test2::before{
  background-color:green;
  content:"前"
}
.test2::after{
  background-color:green;
  content:"後"
}

:not(E) 選擇非 <E> 元素的每一個元素。
.wrapper>:not(.test2){
  background-color:green;
}

:checked input:checked 選擇每一個被選中的input元素。

HTML:

<input type="radio" name="" id="" />

<span>3333</span>

CSS:

input:checked+span{
  border:10px solid red;
}





這裏只提一下本文要用到的CSS選擇器,更多關於CSS3強大的選擇器請移步這裏:全面整理 CSS3 選擇器的用法




實現評分模塊

HTML:

<div class="rating">
        <input type="radio" id="star5" name="rating" value="5" hidden/>
        <label for="star5"></label>
        <input type="radio" id="star4" name="rating" value="4" hidden/>
        <label for="star4"></label>
        <input type="radio" id="star3" name="rating" value="3" hidden/>
        <label for="star3"></label>
        <input type="radio" id="star2" name="rating" value="2" hidden/>
        <label for="star2"></label>
        <input type="radio" id="star1" name="rating" value="1" hidden/>
        <label for="star1"></label>
    </div>

關於input標籤的隱藏,我這裏只要用hidden屬性實現隱藏,固然還有不少實現方式,只要input不佔據文檔的位置可是看不見就OK,咱們須要隱藏單選框,且爲可用性隱藏。這裏還有幾種方式僅供你們參考:

1. display: none;

.rating >input {
        display: none;
    }

2. css3的clip

.rating >input {
        position: absolute;
        clip: rect(0 0 0 0);
    }

3.opcity

.rating >input {
        position: absolute;
        opacity: 0;
    }

CSS:

.rating {
        font-size: 0;
        display: table;
    }

    .rating > label {
        color: #ddd;
        float: right;
    }

    .rating > label:before {
        padding: 5px;
        font-size: 24px;
        line-height: 1em;
        display: inline-block;
        content: "★";
    }

    .rating > input:checked ~ label,
    .rating:not(:checked) > label:hover,
    .rating:not(:checked) > label:hover ~ label {
        color: #FFD700;
    }

    .rating > input:checked ~ label:hover,
    .rating > label:hover ~ input:checked ~ label,
    .rating > input:checked ~ label:hover ~ label {
        opacity: 0.5;
    }

在線預覽地址






展現評分模塊

用戶評完分以後,會看到展現的分數,假設五個星星,滿分10分。

展現評分就比較簡單,放兩個如出一轍的html,五角星顏色不一樣,灰色的放在下面,評分的亮色放在上面,而後按照百分比顯示分數。

HTML:

<div class="star-rating">
        <div class="star-rating-top" style="width:50%">
            <span></span>
            <span></span>
            <span></span>
            <span></span>
            <span></span>
        </div>
        <div class="star-rating-bottom">
            <span></span>
            <span></span>
            <span></span>
            <span></span>
            <span></span>
        </div>
    </div>

CSS:

.star-rating {
        unicode-bidi: bidi-override;
        color: #ddd;
        font-size: 0;
        height: 25px;
        margin: 0 auto;
        position: relative;
        display: table;
        padding: 0;
        text-shadow: 0px 1px 0 #a2a2a2;
    }

    .star-rating span {
        padding: 5px;
        font-size: 20px;
    }
    
    .star-rating span:after {
        content: "★";
    }

    .star-rating-top {
        color: #FFD700;
        padding: 0;
        position: absolute;
        z-index: 1;
        display: block;
        top: 0;
        left: 0;
        overflow: hidden;
        white-space: nowrap;
    }

    .star-rating-bottom {
        padding: 0;
        display: block;
        z-index: 0;
    }

當接口返回的分數是5分的時候,恰好佔據一半的星星,2星半,只要計算出百分比就行,只用管數據,用上vue.js數據驅動的特色來動態展現樣式這個簡直不要太容易。

在線預覽地址:

本文方法好處在於,純CSS驅動,各類切換根本不須要JS,省了很多JS,對於相似這種需求你們也能夠觸類旁通,這裏只提供一些思路,沒有細說;同時圖片背景比較小或者能夠直接不使用圖片,比起使用圖片節省很多資源,和提升些許性能。可是,學習以及理解成本稍高,可能並不適用於全部同行,所以,此文適合喜歡「折騰」的童鞋。

相關文章
相關標籤/搜索