用css畫圖標


css3的屬性 transform(轉換) 用途很廣泛,功能也很強大,為了熟悉它的各種轉換方式(平移 translate,旋轉 rotate,扭曲 skew,放縮 scale),我做了一些平常常用的一些簡單的圖標。

這些圖標很多是通過三角形來拼貼起來的,所以我們需要知道怎么樣畫三角形。

1. 我們要將該 div 的 width 和 height 都設置為 0,三角形是通過設置 border 來實現;

2. 通過我們需要畫成的三角形的目標分析,這個三角形的朝向(只針對規則的朝向:上、右、下、左、上左、上右、下右、下左,不規則的朝向可以通過旋轉來實現);

3. 如果是上、右、下、左四種中的一種,將朝向的對面的 border-color 設置為我們需要的顏色,該朝向的這一邊不設置 border,其它兩邊的 border-color 設置為 transparent;

4. 如果是上左、上右、下右、下左中的一種,以上右為例,設置相關的兩邊:上和右的 border-color 設置成我們想要的顏色,其它兩邊的 border-width 設置成 transparent。

5. border-width 的值就是底邊長和高。

看幾個例子:

例1:

圖形:

該圖形中,只有上方位有邊,這個邊就是三角形的底邊了,底邊長為 3.6em(左右相加),高為 2em。右、下、左沒有邊。於是 border-top-color: #000; | border-right-color: transparent; | border-left-color: transparent; | border-top-width: 2em; | border-right-width: 1.8em; | border-left-width: 1.8em;

.bottom {
    width: 0;
    height: 0;
    border-top: 2em solid #000;
    border-right: 1.8em solid transparent;
    border-left: 1.8em solid transparent;
}

例2:

該圖形中,左和下上方位有邊,朝向為下左,底邊長為 2em(左右相加),左邊長為 4em(上下相加)。

.bottomLeft {
    width: 0;
    height: 0;
    border-width: 2em 1em;
    border-style: solid;
    border-color: transparent transparent #000 #000;
}

例3:

該圖形中,它的朝向並不是上面提到的那八種,實際上它可以通過例 2 順時針旋轉 60° 得到。

.bottomLeftRotate {
    width: 0;
    height: 0;
    border-width: 2em 1em;
    border-style: solid;
    border-color: transparent transparent #000 #000;
    transform: rotate(60deg);
}

好了,進入正題,用 css 畫一些常見的圖標,目的有五個:1. 熟悉三角形的畫法;2. 熟悉 transform 的使用;3. 回顧數學角度計算;4. 回顧定位布局方法;5. 回顧居中顯示方法。

所有的 dom 都基於一個 div,比如下面第一個實例“向上”:

<div class="top"></div>

第二個實例“向右”:

<div class="right"></div>

1. 向上

.top {
    box-sizing: border-box;
    position: relative;
    width: 0;
    height: 0;
    border-right: .9em solid transparent;
    border-bottom: .9em solid #000;
    border-left: .9em solid transparent;
}
.top:after {
    content: ""; /*針對before,after必須加上*/
    position: absolute;
    left: 50%;
    top: .7em;
    margin-left: -.45em; /*寬度的一半,結合 left: 50%; 使用*/
    width: .9em;
    height: 1.3em;
    background-color: #000;
}

2. 向右

.right {
    box-sizing: border-box;
    position: relative;
    width: 1.3em;
    height: .9em;
    background-color: #000;
}
.right:after {
    content: "";
    position: absolute;
    top: 50%;
    left: 1.1em;
    margin-top: -.9em;
    width: 0;
    height: 0;
    border-top: .9em solid transparent;
    border-bottom: .9em solid transparent;
    border-left: .9em solid #000;
}

3. 向下

.bottom {
    box-sizing: border-box;
    position: relative;
    width: .9em;
    height: 1.3em;
    background-color: #000;
}
.bottom:after {
    content: "";
    position: absolute;
    left: 50%;
    top: 1.1em;
    margin-left: -.9em;
    width: 0;
    height: 0;
    border-right: .9em solid transparent;
    border-top: .9em solid #000;
    border-left: .9em solid transparent;
}

4. 向左

.left {
    box-sizing: border-box;
    position: relative;
    width: 0;
    height: 0;
    border-top: .9em solid transparent;
    border-right: .9em solid #000;
    border-bottom: .9em solid transparent;
}
.left:after {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0; /*在絕對定位中,top: 0; bottom: 0; margin: auto; 結合使用能豎直居中*/
    left: .7em;
    margin: auto;
    width: 1.3em;
    height: .9em;
    background-color: #000;
}

以上四個圖標由三角形和長方形拼貼而成。

5. 正確

.true {
    position: relative;
    width: 1.2em;
    height: .3em;
    background-color: #000;
    transform: rotate(60deg);
    transform-origin: right center;
    border-radius: .15em;
}
.true:after {
    content: "";
    position: absolute;
    top: .1em;
    left: -.85em;
    width: 2em;
    height: .3em;
    background-color: #000;
    transform: rotate(60deg);
    transform-origin: right center;
    border-radius: .15em;
}

將 transform-origin 設置為 right center; 是為了好計算相對於它做絕對定位的 after 偽元素的位置。其實根據計算 .true:after 的 top: .15em; left: -.8em; 設置成上面的 top: .1em; left: -.85em; 能讓兩根線的連接處拼貼得更好。

6. 錯誤

.false {
    position: relative;
    width: 2em;
    height: .3em;
    background-color: #000;
    transform: rotate(45deg);
    border-radius: .15em;
}
.false:after {
    content: "";
    position: absolute;
    width: 2em;
    height: .3em;
    background-color: #000;
    transform: rotate(90deg);
    border-radius: .15em;
}

transform-origin 的值默認為 center center 0; 因此只需旋轉 90deg 即可。旋轉也是相對於相對定位的元素,所以這里只需要在原基礎上旋轉 90deg。

7. 菜單

.menu {
    box-sizing: border-box;
    position: relative;
    width: 2em;
    height: 2em;
    background-color: #000;
    border-radius: .3em;
}
.menu:before {
    box-sizing: border-box;
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    margin: auto;
    width: 1.2em;
    height: .15em;
    background-color: #fff;
}
.menu:after {
    box-sizing: border-box;
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    margin: auto;
    width: 1.2em;
    height: .9em;
    border-width: .15em;
    border-style: solid none;
    border-color: #fff;
}

8. 菜單2

.menu2 {
    box-sizing: border-box;
    position: relative;
    width: .5em;
    height: .5em;
    background-color: #000;
    border-radius: 50%;
    cursor: pointer;
}
.menu2:before {
    box-sizing: border-box;
    content: "";
    position: absolute;
    top: 0;
    left: -.75em;
    width: .5em;
    height: .5em;
    background-color: #000;
    border-radius: 50%;
}
.menu2:after {
    box-sizing: border-box;
    content: "";
    position: absolute;
    top: 0;
    left: .75em;
    width: .5em;
    height: .5em;
    background-color: #000;
    border-radius: 50%;
}

9. 下載

.download {
    box-sizing: border-box;
    position: relative;
    width: 2em;
    height: .8em;
    border-width: .3em;
    border-style: none solid solid;
    border-color: #000;
}
.download:before {
    content: "";
    position: absolute;
    right: 0;
    bottom: .7em;
    left: 0;
    margin: auto;
    width: .3em;
    height: 1em;
    background-color: #000;
}
.download:after {
    content: "";
    position: absolute;
    right: 0;
    bottom: .2em;
    left: 0;
    margin: auto;
    width: 0;
    height: 0;
    border-right: .6em solid transparent;
    border-top: .6em solid #000;
    border-left: .6em solid transparent;
}

箭頭下面的“框”,設置 border-top-style:none; 而不是設置 border-top-color: transparent; 這樣做就能實現,應該與上邊框連接處的線那里不會出現線條變細的情況,如下:

這里只是將 border-style 和 border-color 的值換成了 solid 和 transparent #000 #000.

10. 上傳

.upload {
    box-sizing: border-box;
    position: relative;
    width: 2em;
    height: .8em;
    border-width: .3em;
    border-style: none solid solid;
    border-color: #000;
}
.upload:before {
    content: "";
    position: absolute;
    right: 0;
    bottom: .2em;
    left: 0;
    margin: auto;
    width: .3em;
    height: 1em;
    background-color: #000;
}
.upload:after {
    content: "";
    position: absolute;
    right: 0;
    bottom: 1.1em;
    left: 0;
    margin: auto;
    width: 0;
    height: 0;
    border-right: .6em solid transparent;
    border-bottom: .6em solid #000;
    border-left: .6em solid transparent;
}

11. 視頻

.video {
    box-sizing: border-box;
    position: relative;
    width: 1.5em;
    height: 1.2em;
    background-color: #000;
    border-radius: .3em;
}
.video:after {
    content: "";
    position: absolute;
    top: 50%;
    left: 1.4em;
    margin-top: -.7em;
    width: 0;
    height: 0;
    border-top: .7em solid transparent;
    border-right: .6em solid #000;
    border-bottom: .7em solid transparent;
}

12. 語音

.voice {
    box-sizing: border-box;
    position: relative;
    width: 1.4em;
    height: 1em;
    border-width: .2em;
    border-style: none none solid;
    border-color: #000;
    border-radius: 50%;
}
 .voice:before {
    content: "";
    position: absolute;
    right: 0;
    left: 0;
    bottom: .05em;
    margin: auto;
    width: .8em;
    height: 1.3em;
    background-color: #000;
    border-radius: .4em;
}
.voice:after {
    content: "";
    position: absolute;
    right: 0;
    bottom: -.6em;
    left: 0;
    margin: auto;
    width: 0;
    height: 0;
    border-right: .6em solid transparent;
    border-bottom: .4em solid #000;
    border-left: .6em solid transparent;
}

13. 播放

.play {
    box-sizing: border-box;
    position: relative;
    width: 2em;
    height: 2em;
    border: .2em solid #000;
    border-radius: 50%;
}
.play:after {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 50%;
    margin-top: auto;
    margin-bottom: auto;
    margin-left: -.3em; /*沒有讓其左右居中,因為看起來右邊更空一些*/
    width: 0;
    height: 0;
    border-top: .6em solid transparent;
    border-bottom: .6em solid transparent;
    border-left: .9em solid #000;
}

14. 暫停

.pause {
    box-sizing: border-box;
    position: relative;
    width: 2em;
    height: 2em;
    border: .2em solid #000;
    border-radius: 50%;
}
.pause:before {
    box-sizing: border-box;
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 50%;
    margin-top: auto;
    margin-bottom: auto;
    margin-left: -.35em;
    width: .2em;
    height: .9em;
    background-color: #000;
}
.pause:after {
    box-sizing: border-box;
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 50%;
    margin-top: auto;
    margin-bottom: auto;
    margin-left: .15em;
    width: .2em;
    height: .9em;
    background-color: #000;
}

 15. 上一首(集)

.previous {
    box-sizing: border-box;
    position: relative;
    width: 2em;
    height: 2em;
    border: .2em solid #000;
    border-radius: 50%;
}
.previous:before {
    box-sizing: border-box;
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 50%;
    margin-top: auto;
    margin-bottom: auto;
    margin-left: -.65em;
    width: 0;
    height: 0;
    border-top: .45em solid transparent;
    border-bottom: .45em solid transparent;
    border-right: .6em solid #000;
}
.previous:after {
    box-sizing: border-box;
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 50%;
    margin-top: auto;
    margin-bottom: auto;
    margin-left: -.2em;
    width: 0;
    height: 0;
    border-top: .45em solid transparent;
    border-bottom: .45em solid transparent;
    border-right: .6em solid #000;
}

16. 下一首(集)

.next {
    box-sizing: border-box;
    position: relative;
    width: 2em;
    height: 2em;
    border: .2em solid #000;
    border-radius: 50%;
}
.next:before {
    box-sizing: border-box;
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 50%;
    margin-top: auto;
    margin-bottom: auto;
    margin-left: -.4em;
    width: 0;
    height: 0;
    border-top: .45em solid transparent;
    border-bottom: .45em solid transparent;
    border-left: .6em solid #000;
}
.next:after {
    box-sizing: border-box;
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 50%;
    margin-top: auto;
    margin-bottom: auto;
    margin-left: .05em;
    width: 0;
    height: 0;
    border-top: .45em solid transparent;
    border-bottom: .45em solid transparent;
    border-left: .6em solid #000;
}

17. 停止

.stop {
    box-sizing: border-box;
    position: relative;
    width: 2em;
    height: 2em;
    border: .2em solid #000;
    border-radius: 50%;
}
.stop:after {
    box-sizing: border-box;
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    margin: auto;
    width: .9em;
    height: .9em;
    background-color: #000;
}

18. 當前位置

.position {
    position: relative;
    width: .6em;
    height: .6em;
    border: .4em solid #000;
    border-radius: 50%;
}
.position:after {
    content: "";
    position: absolute;
    top: .55em;
    left: -.4em;
    width: 0;
    height: 0;
    border-top: 1em solid #000;
    border-right: .7em solid transparent;
    border-left: .7em solid transparent;
    border-top-left-radius: 50%;
    border-top-right-radius: 50%;
}

勉強看起來像,中間的圓,不圓了。

19. pc

.pc {
    box-sizing: border-box;
    position: relative;
    width: 2em;
    height: 1.4em;
    border-width: .2em .2em .3em;
    border-style: solid;
    border-color: #000;
    border-radius: .2em;
    background-color: #efefef;
}
.pc:before {
    content: "";
    position: absolute;
    top: 1.2em;
    right: 0;
    left: 0;
    margin: auto;
    width: .6em;
    height: .4em;
    background-color: #000;
}
.pc:after {
    content: "";
    position: absolute;
    top: 1.6em;
    right: 0;
    left: 0;
    margin: auto;
    width: 1.6em;
    height: .2em;
    background-color: #000;
}

20. phone

.phone {
    box-sizing: border-box;
    position: relative;
    width: 1.4em;
    height: 2em;
    background-color: #efefef;
    border-width: .3em .2em .5em;
    border-style: solid;
    border-color: #000;
    border-radius: .15em;
}
.phone:after {
    content: "";
    position: absolute;
    right: 0;
    bottom: -.4em;
    left: 0;
    margin: auto;
    width: .5em;
    height: .3em;
    background-color: #fff;
    border-radius: .3em;
}

21. 搜索

.search {
    box-sizing: border-box;
    position: relative;
    width: 1em;
    height: .3em;
    background-color: #000;
    border-top-right-radius: .15em;
    border-bottom-right-radius: .15em;
    transform: rotate(40deg);
    transform-origin: right center;
}
 .search:before {
    content: "";
    position: absolute;
    left: -1.3em;
    bottom: -.6em;
    width: 1em;
    height: 1em;
    border: .3em solid #000;
    border-radius: 50%;
} 

22. 五角星

.star {
    box-sizing: border-box;
    position: relative;
    width: 0;
    height: 0;
    border-top: .7em solid #000;
    border-right: 1em solid transparent;
    border-left: 1em solid transparent;
}
.star:before {
    content: "";
    position: absolute;
    top: -.7em;
    left: -1em;
    width: 0;
    height: 0;
    border-top: .7em solid #000;
    border-right: 1em solid transparent;
    border-left: 1em solid transparent;
    transform: rotate(72deg);
}
.star:after {
    content: "";
    position: absolute;
    top: -.7em;
    left: -1em;
    width: 0;
    height: 0;
    border-top: .7em solid #000;
    border-right: 1em solid transparent;
    border-left: 1em solid transparent;
    transform: rotate(-72deg);
}

根據多邊形的內角和公式可知 360*(5-2) / 5 = 72°。剩下的調整一下位置就好了。這個五角星由三個三角形拼貼而成。

23. 電子郵件

.email {
    box-sizing: border-box;
    position: relative;
    width: 0;
    height: 0;
    border-width: .7em 1em;
    border-style: solid;
    border-color: transparent transparent #000 #000;
}
.email:before {
     content: "";
     position: absolute;
     top: -.7em;
     left: 1em;
     transform: rotateY(180deg);
     transform-origin: left center;
    width: 0;
    height: 0;
    border-width: .7em 1em;
    border-style: solid;
    border-color: transparent transparent #000 #000;
}
.email:after {
    content: "";
    position: absolute;
    top: -.7em;
    left: 50%;
    margin-left: -.9em;
    width: 0;
    height: 0;
    border-top: .6em solid #000;
    border-right: .9em solid transparent;
    border-left: .9em solid transparent;
}

24. 眼睛

.eye {
    box-sizing: border-box;
    position: relative;
    width: 2em;
    height: 1.2em;
    background-color: #000;
    border-radius: 50%;
}
.eye:before {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    margin: auto;
    width: .8em;
    height: .8em;
    background-color: #fff;
    border-radius: 50%;
}
.eye:after {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    margin: auto;
    width: .4em;
    height: .4em;
    background-color: #000;
    border-radius: 50%;
}

25. 未鎖

.unlock {
    box-sizing: border-box;
    position: relative;
    width: 1.6em;
    height: 1.4em;
    background-color: #000;
    border-radius: .2em;
}
.unlock:before {
    box-sizing: border-box;
    content: "";
    position: absolute;
    top: -.4em;
    right: -.4em;
    width: 1em;
    height: .6em;
    border-width: .2em;
    border-style: solid solid none;
    border-color: #000;
    border-radius: .5em;
}
.unlock:after {
    box-sizing: border-box;
    content: "";
    position: absolute;
    bottom: .2em;
    left: 50%;
    margin-left: -.15em;
    width: .3em;
    height: .5em;
    border-top-left-radius: .25em;
    border-top-right-radius: .25em;
    background-color: #fff;
}

這里 .unlock:before 設置了 border-radius: .5em; 所以導致 被打開的鎖下邊框位置的部分看起來很細。

26. 杯子

.cup {
    box-sizing: border-box;
    position: relative;
    width: 1.3em;
    height: 2em;
    border-width: .2em .2em 1.2em;
    border-style: solid;
    border-color: #000;
    background-color: #efefef;
    border-bottom-left-radius: .3em;
    border-bottom-right-radius: .3em;
}
.cup:before {
    box-sizing: border-box;
    content: "";
    position: absolute;
    top: .1em;
    left: -.7em;
    width: .7em;
    height: 1.4em;
    border-width: .2em;
    border-style: solid;
    border-color: #000;
    border-top-left-radius: .3em;
    border-bottom-left-radius: .3em;
}

27. 心

.heart {
    position: relative;
    width: 1.4em;
    height: 2em;
    background-color: #000;
    border-top-left-radius: 1em;
    border-top-right-radius: 1em;
    transform: rotate(-45deg);
    transform-origin: center bottom;
}
.heart:after {
    content: "";
    position: absolute;
    top: -.7em;
    left: -.7em;
    width: 1.4em;
    height: 2em;
    background-color: #000;
    border-top-left-radius: 1em;
    border-top-right-radius: 1em;
    transform: rotate(90deg);
    transform-origin: center bottom;
}

該愛心由兩個柱子一樣的東西拼貼而成,很粗魯,所以它是是黑色。

28. 主頁

.home {
    box-sizing: border-box;
    position: relative;
    width: 1.4em;
    height: 1em;
    background-color: #000;
}
 .home:before {
    content: "";
    position: absolute;
    top: -.7em;
    left: 50%;
    margin-left: -1em;
    border-left: 1em solid transparent;
    border-right: 1em solid transparent;
    border-bottom: .8em solid #000;
}
.home:after {
    z-index: 2;
    content: "";
    position: absolute;
    right: 0;
    bottom: 0;
    left: 0;
    margin: auto;
    width: .3em;
    height: .5em;
    background-color: #fff;
}

29. 密碼

.password {
    box-sizing: border-box;
    position: relative;
    width: 1.8em;
    height: 1.4em;
    background-color: #000;
    border-radius: .2em;
}
.password:before {
    box-sizing: border-box;
    content: "";
    position: absolute;
    top: -.6em;
    left: 50%;
    margin-left: -.5em;
    width: 1em;
    height: 1em;
    border: .2em solid #000;
    border-radius: 50%;
}
.password:after {
    box-sizing: border-box;
    content: "";
    position: absolute;
    bottom: .2em;
    left: 50%;
    margin-left: -.15em;
    width: .3em;
    height: .5em;
    border-top-left-radius: .25em;
    border-top-right-radius: .25em;
    background-color: #fff;
}

30. 用戶(賬號)

.user {
    box-sizing: border-box;
    position: relative;
    width: .9em;
    height: .9em;
    background-color: #000;
    border-radius: 50%;
}
.user:after {
    content: "";
    position: absolute;
    top: 1em;
    left: 50%;
    margin-left: -.9em;
    width: 1.8em;
    height: 1em;
    background-color: #000;
    border-top-left-radius: .9em;
    border-top-right-radius: .9em;
}

 

更新:(2017-06-27)

對於菜單的圖標,可以不使用生成內容 content 屬性及偽元素 before 和 after 。如下面的圖標:

可以通過一段很簡短的 css 實現:

#menu {
    color: #000;
display: block; width: 50px; height: 50px; box-sizing: border-box; border-top: 10px solid; /*沒有設置顏色值,將同文本顏色一樣*/ border-bottom: 10px solid; padding-top: 10px; padding-bottom: 10px; background-color: currentColor; /*顏色關鍵字,將同文本顏色一致*/ background-clip: content-box; /*背景將繪制在內容方框內*/ }

上面的代碼可以更簡短一些,比如不設置 box-sizing 和 height 屬性,結果是一樣的,三條短橫線的高度和它們之間的間距一樣均為 10px ,要是在 less 預處理器中可這樣寫:

#menu {
  @size: 10px;
  color: #000;
displsy: block; width: @size * 5;
height: @size * 5; border-top: @size solid; border-bottom: @size solid; padding-top: @size; padding-bottom: @size; background-color: currentColor; background-clip: content-box; }

如果需要整體調整圖標的大小,改變 @size 變量的值就行了。如果寬度需要稍微寬點,將乘號 “*” 后面的數值變大就行了。

 

更新:(2019-08-27)

在繪制邊框的時候,有一個 border-style 的值為 double 的邊框屬性,可以據此制作出形如軌道的效果

受這個效果的啟發,同樣可以僅通過邊框就制作出一個菜單圖標

<div class="double"></div>
.double {
    width: 50px;
    height: 7px;
    border-top: 21px double #000;
    border-bottom: 7px solid #000;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM