這個line list的名字是我本身起的(大概的意思是單行列表),要實現的東西爲sheral的line list,對應的scss組件爲_line-list.scss
,下圖爲line-list的一個縮影:php
這個UI應該是每一個移動端網頁都必備的,並且使用場景也是很是的豐富,因此這裏咱們採用一步步按部就班的方式去重構。css
先說下整個過程當中要解決的問題:html
.line-list>.line-item
結構方面,標籤能夠是ul.line-list>.line-item
或者div.line-list>a.line-item
,前者用於單頁應用,後者用於連接跳轉。ios
.line-item { @extend %bar-line; } .line-list { background: #fff; + .line-list { margin-top: 10px; } }
因爲這種line item的樣式使用場景較多,因此咱們封裝了一個%bar-line
,定義在sandal的_mixin.scss
文件中(下面如無特殊說明,mixin和%均在該文件定義),以下:git
// bar line %bar-line { line-height: $barHeight - 10px; padding: 5px 10px; position: relative; display: block; overflow: hidden; @if $activeStateSwitch{ //是否開啓:active樣式 &:active, &:hover { background-color: darken($colorF, 3%); } } &:not(:irst-of-type)::before { // 使用僞元素生成retina 1px content: ""; @include retina-one-px-border; } }
下面解讀下上面的SCSS代碼:github
retina-one-px-border($direction: top, $color: $colorBorder)
,直接傳入相應參數調用便可。1px
掛在除第一個元素以外的僞元素before
上,而第一個最上面和最後一個最下面的1px
將會在父元素上實現,那樣中間line-item
之間的1px
就很容易擴展實現縮進。44px
(ios 的標準高度爲44px),實現方法爲line-height + padding
,爲何不是直接line-height:44px
,這就涉及到咱們下面更多的擴展形態了。保持HTML結構不變,追加class實現所需的功能:web
item
之間的1px
縮進,最開始和最末位的不縮進.line-list--indent { @extend %border-tb; // 添加最上和最下的1px,造成封閉 .line-item::before { left: 10px; // 縮進10px } } .line-list--after-v { // 右箭頭經過after生成 .line-item { padding-right: 30px; @extend %item-v-right; } }
這裏縮進用的僞元素
before
的1px left
定位來實現的,看到過有些方法是設置item
的border-bottom
,而後設置item
的margin-left: 10px
,這種實現方法是錯誤的,由於點擊的不是整行了(缺了margin-left
的10px
),固然也能夠內嵌一個inner元素設置inner元素的margin-left
,或空元素定位等app
一樣考慮到比較經常使用,在sandal中封裝了兩個%
,分別爲%border-tb
,%item-v-right
,具體代碼爲:佈局
// border top & bottom %border-tb { position: relative; &::before { content: ""; @include retina-one-px-border(top); z-index: 1; // 第一個元素點擊的時候防止active背景色遮蓋了1px } &::after { content: ""; @include retina-one-px-border(bottom); } } // item arrow, 右側箭頭跳轉指向 %item-v-right { &::after { content: ""; @include v-arrow; color: $colorC; position: absolute; right: 15px; top: 50%; margin-top: -1px; transform: rotate(45deg) translate(0, -50%); box-sizing: border-box; } }
選擇模式分爲單選和多選,單選一樣能夠保持結構不變,經過after
元素生成選中的對鉤;而多選則能夠添加i.icon-checbox
元素。對鉤和icon checkbox都是CSS繪製,使用currentColor
,item
選中時直接改變color便可,具體代碼以下:flex
// 單選 .line-list--select { .line-item { padding-right: 30px; &.active { color: $primary; // 選中改變顏色 &::after { // 僞元素生成對鉤 content: ""; display: block; width: 14px; height: 8px; border-bottom: 2px solid currentColor; border-left: 2px solid currentColor; transform: rotate(-52deg) translate(0, -50%); box-sizing: border-box; position: absolute; top: 50%; right: 8px; margin-top: -4px; } } } } // 多選 .line-list--multi-select { .active{ color: $primary; .icon-checkbox{ color: $primary; } } }
這裏咱們將採用flex,一行大概分爲三欄:圖標icon(固定寬度),中間內容(剩餘寬度),右邊操做或提示(switch,提示文字或數字,右箭頭)。若是你要兼容的手機不支持flex,那也不要緊,這個結構也足夠你使用絕對定位或float佈局了,徹底不須要再更改結構。
.line-list--flex { .line-item { display: flex; align-items: center; padding-right: 0; .item-icon, .item-img, .icon-switch, .remind-num, .item-append{ margin-right: 10px; } .item-bd { // 中間內容 flex: 1; margin-right: 10px; width: 1%; } .item-append{ color: $color9; } .icon-v-right { width: 30px; height: 30px; color: $colorC; margin-left: -10px; } .remind-num { position: static; line-height: 1.5; } } }
打造好了line-list
,就能夠普遍應用於其餘地方了,如actionsheet,filter,popover等各類地方。