Github 地址 (可查看交互效果)css
切圖的三個境界:html
給不一樣頁面添加不一樣類,標識不一樣頁面,而後設置當前頁面樣式,覆蓋掉默認樣式。前端
代碼:css3
<div class="demo1"> <ul class="nav"> <li class="nav-item item-home">首頁</li> <li class="nav-item item-demo1">導航高亮</li> </ul> </div>
.nav { padding: 5px 10px; background: #000; color: #fff; } .nav .nav-item { display: inline-block; margin-right: 10px; list-style: none; opacity: 0.5; cursor: pointer; &:hover { opacity: 1; } } .demo1 .nav.nav-item.item-demo1 { opacity: 1; }
本身的想法:這種方式雖然好,可是,須要爲每一個導航都寫一個默認和高亮樣式,若是不是同一我的寫的代碼,在新增導航的時候,很容易會忘記去加上。git
看到後面的時候,發現書中有這個問題相關的回答,能夠用 sass 進行 for 循環實現。同時,還能夠定義主題色變量。github
hover 到某個菜單時,顯示子菜單。sass
代碼:less
<!-- html --> <div class="demo2"> <ul class="nav"> <li class="nav-item item-home">首頁</li> <li class="nav-item item-demo1">導航高亮</li> <li class="menu"> <ul> <li>導航高亮-下級1</li> <li>導航高亮-下級2</li> </ul> </li> <li class="nav-item item-demo2">導航懸浮顯示下級</li> <li class="menu"> <ul> <li>導航懸浮顯示下級-下級1</li> <li>導航懸浮顯示下級-下級2</li> </ul> </li> </ul> </div>
// less .nav { position: relative; padding: 5px 10px; background: #06a992; color: #fff; } .nav .nav-item { display: inline-block; margin-right: 10px; list-style: none; opacity: 0.5; cursor: pointer; &:hover { // <-- 在導航菜單上須要加 hover opacity: 1; } } .demo2 .nav .nav-item.item-demo2 { opacity: 1; } .nav-item:hover + .menu{ display: list-item; } .menu { display: none; position: absolute; top: 44px; min-width: 100px; color: #000; border: 1px solid #000; box-shadow: 0 0 5px; &:before { // <-- 加一個僞元素,能夠避免當下拉列表和導航菜單名稱之間有空隙時,鼠標往下移到下拉列表的過程當中,脫離導航菜單名稱而隱藏下拉列表的狀況 content: ""; position: absolute; left: 0; top: -20px; width: 100%; height: 20px; } &:hover { // <-- 隱藏元素自己也須要加 hover display: list-item; } } ul, ul li { list-style: none; }
本身的想法:書中提到,能夠經過 absolute 給 .menu 定位,我想了很久,都想不出來怎麼實現,若是有實現方法的,請告知,謝謝!佈局
對上面的 demo 作了佈局的改變,如今能夠簡單的經過 absolute 來定位了,參考:flex
代碼:
<!-- html --> <div class="demo2"> <nav> <ul class="nav-ul"> <li class="nav-item item-home">首頁</li> </ul> <ul class="nav-ul"> <li class="nav-item item-demo1">導航高亮</li> <li class="menu"> <ul class="menu-ul"> <li>導航高亮-下級1</li> <li>導航高亮-下級2</li> </ul> </li> </ul> <ul class="nav-ul"> <li class="nav-item item-demo2">導航懸浮顯示下級</li> <li class="menu"> <ul class="menu-ul"> <li>導航懸浮顯示下級-下級1</li> <li>導航懸浮顯示下級-下級2</li> </ul> </li> </ul> </nav> </div>
// less nav { font-size: 0; } .nav-ul { display: inline-block; position: relative; padding: 5px 10px; font-size: 16px; background: #06a992; color: #fff; } .nav-ul .nav-item { display: inline-block; margin-right: 10px; list-style: none; opacity: 0.5; cursor: pointer; &:hover { opacity: 1; } } .demo2 .nav-ul .nav-item.item-demo2 { opacity: 1; } .nav-item:hover + .menu{ display: list-item; } .menu { display: none; position: absolute; top: 44px; min-width: 100px; white-space: nowrap; color: #000; border: 1px solid #000; box-shadow: 0 0 5px; &:before { // <-- 加一個僞元素,能夠避免當下拉列表和導航菜單名稱之間有空隙時,鼠標往下移到下拉列表的過程當中,脫離導航菜單名稱而隱藏下拉列表的狀況 content: ""; position: absolute; left: 0; top: -20px; width: 100%; height: 20px; } &:hover { display: list-item; } .menu-ul { padding-right: 1.2em; } } ul, ul li { list-style: none; }
代碼:
<template> <div class="demo2"> <nav> <ul class="nav-ul"> <li class="nav-item item-home">首頁</li> </ul> <ul class="nav-ul" @mouseover="showSubmenu = true" @mouseout="showSubmenu = false"> <li class="nav-item item-demo1">導航高亮</li> <li class="menu" :style="{ display: showSubmenu ? 'block' : 'none' }"> <ul class="menu-ul"> <li>導航高亮-下級1</li> <li>導航高亮-下級2</li> </ul> </li> </ul> <ul class="nav-ul"> <li class="nav-item item-demo2">導航懸浮顯示下級</li> <li class="menu"> <ul class="menu-ul"> <li>導航懸浮顯示下級-下級1</li> <li>導航懸浮顯示下級-下級2</li> </ul> </li> </ul> </nav> </div> </template> <script> export default { name: 'demo-nav-hover-show1', data() { return { showSubmenu: false, // <-- 代碼僅做爲演示用 }; }, }; </script>
能夠看到,加了 mouse 事件後,鼠標懸浮後,會在元素的 style 中加上 display: none;
,致使 css 中的樣式失效:
意外狀況:移動端 Safari 上,觸摸會觸發 CSS 的 hover,hover 會很高几率地先於 touchstart 事件,此時會判斷當前是顯示仍是隱藏狀態,因爲 CSS 的 hover 發揮了做用,因此判斷爲顯示,而後又把它隱藏了。也就是說,點一次不出來,要點兩次。因此最好別兩個同時寫。
代碼:
<div class="demo"> <ul class="nav"> <li class="nav-item item-home"> <span>首頁</span> </li> <li class="nav-item item-demo"> <span>鼠標懸浮顯示下級下拉菜單</span> <ul class="menu-ul"> <li>導航懸浮顯示下級-下級1</li> <li>導航懸浮顯示下級-下級2</li> </ul> </li> </ul> </div>
.nav { padding: 5px 10px; background: #06a992; color: #fff; } .nav .nav-item { position: relative; display: inline-block; margin-right: 10px; list-style: none; opacity: 0.5; cursor: pointer; &:hover { opacity: 1; .menu-ul { display: block; } } } .demo .nav .nav-item.item-demo { opacity: 1; } .menu-ul { display: none; position: absolute; left: 0; top: 44px; min-width: 100px; padding-right: 1.2em; white-space: nowrap; border: 1px solid #000; box-shadow: 0 0 5px; color: #000; background-color: #fff; &:before { // <-- 加一個僞元素,能夠避免當下拉列表和導航菜單名稱之間有空隙時,鼠標往下移到下拉列表的過程當中,脫離導航菜單名稱而隱藏下拉列表的狀況 content: ""; position: absolute; left: 0; top: -20px; width: 100%; height: 20px; } } ul, ul li { list-style: none; }
使用子元素的話,hover 可直接加在父容器上,隱藏元素自己不須要加 hover。
可使用 :checked 代替鼠標點擊事件。
代碼:
<!--html--> <div class="radio-checkbox"> <label class="control-label"> <input type="radio" value="value1" name="radio"> radio1: <span class="radio"></span> </label> <label class="control-label"> <input type="radio" value="value2" name="radio"> radio2: <span class="radio"></span> </label> <label class="control-label"> <input type="checkbox" value="value1"> checkbox <span class="checkbox"></span> </label> </div>
// less input[type=checkbox], input[type=radio] { display: none; } .control-label { margin-right: 10px; display: inline-block; cursor: pointer; } .radio { position: relative; display: inline-block; width: 16px; height: 16px; vertical-align: middle; border: 1px solid #3eaf7c; border-radius 50%; } input[type=radio]:checked + .radio { box-shadow: 0 0 3px #3eaf7c; &:after { content: ''; width: 50%; height: 50%; display: block; position: absolute; left: 50%; top: 50%; transform: translateX(-50%) translateY(-50%); background: #3eaf7c; border-radius 50%; } } .checkbox { position: relative; display: inline-block; width: 16px; height: 16px; vertical-align: middle; border: 1px solid #3eaf7c; } input[type=checkbox]:checked + .checkbox { box-shadow: 0 0 3px #3eaf7c; &:after { content: '✓'; display: block; position: absolute; left: 50%; top: 50%; transform: translateX(-50%) translateY(-50%); color: #3eaf7c; } }
使用 :checked 屬性時,要注意兼容性:
設置一個很大的 padding-bottom,這樣容器被最大的子元素撐開時,其餘的子元素使用能夠用 padding-bottom 來補償缺乏的高度。而後設置一個同方向的 margin-bottom 負值,能夠抵消設置的 padding-bottom。 同時設置父容器的 overflow: hidden;
,將多餘的部分裁剪(隱藏)掉。
代碼:
<!--html--> <div class="demo"> <div class="col col1"> <p class="title">蘋果</p> <p class="des"> 蘋果,是水果中的一種,是薔薇科蘋果亞科蘋果屬植物,其樹爲落葉喬木。 </p> </div> <div class="col col2"> <p class="title">香蕉</p> <p class="des"> 香蕉(學名:Musa nana Lour.)芭蕉科芭蕉屬植物,又指其果實,熱帶地區普遍種植。 </p> </div> <div class="col col3"> <p class="title">水蜜桃</p> <p class="des"> 水蜜桃(學名:Prunus persica 、meltingfleshed peach):薔薇科、桃屬植物。南方品種羣中肉質柔軟多汁呈軟溶質的一類品種。果實頂部平圓,熟後易剝皮,多粘核。 </p> </div> <div class="col col4"> <p class="title">菠蘿</p> <p class="des"> 菠蘿(學名:Ananas comosus),是熱帶水果之一。 </p> </div> </div>
// less .demo { overflow: hidden; } .col { float: left; width: 20%; padding-top: 10px; padding-left: 10px; padding-right: 10px; padding-bottom 2000px; // <-- 設置 padding-bottom margin-bottom: -2000px; // <-- 設置 margin-bottom margin-right: 10px; border: 1px solid #000; border-radius: 5px; }
缺點:底部的 border 沒有了,底部圓角也不顯示了。
table 中的每一個 td 都是等高的,因此能夠設置容器 display: table;
,設置裏面的子元素 display: table-cell;
。將子元素的寬度設大點,能夠實現等分。
代碼:
// stylus
.demo
display table
border-spacing 20px // <-- 設置間隔
word-break break-all
.col
display table-cell
width 1000px // <-- 設置很大的寬度,table 自動平分寬度
padding: 10px
border 1px solid #000
border-radius 5px
注意:雖然 table 佈局能夠實現等分,可是有一種狀況須要注意,就是英文單詞很長,沒有設置 word-break 的時候,這種狀況是不會自動等分的。
這種佈局的另外一個好處,就是能夠在媒體查詢時,實現響應式。
能夠嘗試拉伸屏幕,觀察下面的佈局變化。(大屏顯示每行四列,中屏顯示每行兩列,小屏顯示每行一列。)
代碼:
<!--html--> <div class="demo"> <div class="col col1"> <p class="title">蘋果</p> <p class="des"> 蘋果,是水果中的一種,是薔薇科蘋果亞科蘋果屬植物,其樹爲落葉喬木。 </p> </div> <div class="col col2"> <p class="title">香蕉</p> <p class="des"> 香蕉(學名:Musa nana Lour.)芭蕉科芭蕉屬植物,又指其果實,熱帶地區普遍種植。 </p> </div> <!--加了個 tr 實現一行兩列布局--> <span class="tr"></span> <div class="col col3"> <p class="title">水蜜桃</p> <p class="des"> 水蜜桃(學名:Prunus persica 、meltingfleshed peach):薔薇科、桃屬植物。南方品種羣中肉質柔軟多汁呈軟溶質的一類品種。果實頂部平圓,熟後易剝皮,多粘核。 </p> </div> <div class="col col4"> <p class="title">菠蘿</p> <p class="des"> 菠蘿(學名:Ananas comosus),是熱帶水果之一。 </p> </div> </div>
// stylus
.demo
display table
border-spacing 20px // <-- 設置間隔
word-break break-all
.col
display table-cell
width 1000px // <-- 設置很大的寬度,table 自動平分寬度
padding: 10px
border 1px solid #000
border-radius 5px
.tr
display none
@media (max-width: 500px)
.demo
display block // <-- 能夠覆蓋原來的樣式,實現響應式佈局
.col
display block // <-- 能夠覆蓋原來的樣式,實現響應式佈局
width: 100%
@media (max-width: 1024px) and (min-width: 501px)
.tr
display table-row // <-- 實現一行兩列布局
能夠看到,從一行兩列布局拉伸到寬屏時,.tr 的 display: none;
不起做用了。由於 table 佈局已經計算好了。要解決這個問題,須要藉助 JavaScript。
代碼:
<!--html--> <div class="demo"> <div class="col col1"> <p class="title">蘋果</p> <p class="des"> 蘋果,是水果中的一種,是薔薇科蘋果亞科蘋果屬植物,其樹爲落葉喬木。 </p> </div> <div class="col col2"> <p class="title">香蕉</p> <p class="des"> 香蕉(學名:Musa nana Lour.)芭蕉科芭蕉屬植物,又指其果實,熱帶地區普遍種植。 </p> </div> <div class="col col3"> <p class="title">水蜜桃</p> <p class="des"> 水蜜桃(學名:Prunus persica 、meltingfleshed peach):薔薇科、桃屬植物。南方品種羣中肉質柔軟多汁呈軟溶質的一類品種。果實頂部平圓,熟後易剝皮,多粘核。 </p> </div> <div class="col col4"> <p class="title">菠蘿</p> <p class="des"> 菠蘿(學名:Ananas comosus),是熱帶水果之一。 </p> </div> </div>
// less .demo { display: flex; word-break break-all .col { width: 25%; padding: 10px; margin: 0 10px; border: 1px solid #000; border-radius: 5px; } }
需求:
例若有 1 ~ 3 個 item 顯示在同一行,但 item 的個數不必定,若是隻有 1 個,那 item 佔寬 100%;若是有 2 個,每一個佔 50%;若是有 3 個,每一個佔 33%。
:nth-last-child(an+b) 這個 CSS 僞類匹配文檔樹中在其以後具備 an+b-1 個兄弟節點的元素,其中 n 爲正值或零值。它基本上和 :nth-child 同樣,只是它從結尾處反序計數,而不是從開頭處。MDN
代碼:
<!--html--> <div class="demo"> <ul class="list clearfix"> <li class="list-item">一行 1 個</li> </ul> <ul class="list clearfix"> <li class="list-item">一行 2 個</li> <li class="list-item">一行 2 個</li> </ul> <ul class="list clearfix"> <li class="list-item">一行 3 個</li> <li class="list-item">一行 3 個</li> <li class="list-item">一行 3 個</li> </ul> </div>
// less .demo { width: 100%; .list { .list-item { display: inline-block; float: left; text-align: center; border: 1px solid #000; box-sizing: border-box; // <-- 設置 box-sizing background-color: #4abf8a; &:nth-child(2) { background-color: #3a8ee6; } &:nth-child(3) { background-color: yellow; } width: 100%; // <-- 一行顯示一個時,使用該樣式 &:first-child:nth-last-child(2), &:first-child:nth-last-child(2) ~ .list-item { // <-- 一行顯示兩個時,使用該樣式,&:first-child:nth-last-child(2) 指向第一個元素 width: 50%; } &:first-child:nth-last-child(3), &:first-child:nth-last-child(3) ~ .list-item { // <-- 一行顯示兩個時,使用該樣式,&:first-child:nth-last-child(2) 指向第一個元素 width: 33.3%; } } } }
須要注意的是,若是 item 有 border,這樣設置是不行的,由於 border 也會佔據必定的寬度。設置一下 box-sizing: border-box; 便可。
需求:
手機屏幕比較小,左邊圖標比較多,一行排不下,把右邊的電話換行,隱藏豎線。(左邊圖標個數不定)
感受需求描述不完整,想象不出這種場景,沒法實現代碼。
代碼:
<!--html--> <form class="form"> <p>利用 :focus 僞類實現 focus 時,放大鏡顏色加深。</p> <div class="form-group"> <label for="search" class="form-label"></label> <div class="form-control"> <input class="form-control-input" id="search" type="text"> <i class="icon-search fas fa-search"></i> </div> </div> <p>利用 :invalid 僞類進行校驗。</p> <div class="form-group"> <label for="email" class="form-label"></label> <div class="form-control"> <input class="form-control-input" id="email" type="email"> <span class="btn">Next</span> </div> </div> </form>
// less .form-control { position: relative; } .form-control-input { padding: 0 32px; &:focus + .icon-search { // <-- :focus 僞類 color: #3eaf7c; } &:invalid + .btn { // <-- :invalid 僞類 opacity: .5; cursor: default; } } .icon-search { position: absolute; left: 10px; top: 14px; color: #ddd; } .btn { height: 40px; line-height: 1.5; padding: 5px 10px; position: absolute; right: 0; top: 0; transform: translateX(100%); border: 1px solid #3eaf7c; border-radius: 3px; background: #3eaf7c; color: #fff; cursor: pointer; }
需求:
hover 時顯示提示信息。不想用 title,也不想用 JavaScript,更不想引入第三方庫。
代碼:
<!--html--> <p> Hello <span class="tip" data-title="Frontend Development">FED</span> </p>
// less .tip { position: relative; &:hover:before { padding: 5px; content: attr(data-title); position: absolute; left: 50%; top: -230%; transform: translateX(-50%); white-space: nowrap; border-radius: 5px; background: #000; color: #fff; } &:hover:after { position: absolute; top: -10px; left: 50%; transform: translateX(-50%); content: ''; width: 0; height: 0; border-style: solid; border-width: 12px; border-color: transparent; border-top-color: #000; } }