純css實現手機通信錄

咱們常常在手機上看到通信錄列表,這類佈局通常有兩個顯著的效果css

20181016202731.png

  1. 首字母吸頂
  2. 快速定位

下面咱們來實現一下html

頁面結構

這裏頁面結構很簡單,就是兩個列表前端

<div class="con">
    <!--聯繫人列表-->
    <div class="contacts" id="contacts">
        <dl>A</dt>
        <dt>a1</dt>
        <dt>a2</dt>
        <dl>B</dt>
        <dt>b1</dt>
        <dt>b2</dt>
        ...
    </div>
    <!--導航列表-->
    <div class="index" id="index">
        <a>A</a>
        <a>B</a>
    </div>
</div>

而後加點樣式後端

html,body{
    margin: 0;
    height: 100%;
    padding: 0;
}
dl,dd{
    margin: 0;
}
.con{
    position: relative;
    height: 100%;
    overflow-x: hidden;
}
.index{
    position: absolute;
    right: 0;
    top: 0;
    bottom: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
}
.index a{
    display: block;
    width: 30px;
    height: 30px;
    text-align: center;
    line-height: 30px;
    border-radius: 50%;
    background: cornflowerblue;
    text-decoration: none;
    color: #fff;
    outline: 0;
    margin: 5px;
}
.contacts{
    height: 100%;
    background: #fff;
    overflow: auto;
    line-height: 2em;
}
.contacts dt{
    background: bisque;
    font-size: 1.5rem;
    color:cornflowerblue;
    height: 2em;
    line-height: 2em;
    padding: 0 10px;
}
.contacts dd{
    padding: 0 10px;
    display: block;
    cursor: pointer;
}

這樣就能夠看到佈局了瀏覽器

https://codepen.io/xboxyan/pe...佈局

實現吸頂效果

吸頂效果其實很簡單,只要用到css中的新屬性position:sticky就能夠了性能

粘性定位元素(stickily positioned element)是計算後位置屬性爲 sticky 的元素。

兼容性還不錯,至少在移動端能夠放心使用flex

20181016204441.png

.contacts dt加上position:stickyspa

.contacts dt{
    /*添加以下屬性*/
    position: sticky;
    top: 0;
}

這樣就實現了每一個類目吸頂效果code

https://codepen.io/xboxyan/pe...

實現快速定位效果

若是不用js,那麼可採用href錨點的方式來實現定位

具體作法就是

<a href='#A'></a>

...

...


<div id='A'></div>

若是整個頁面是能夠滾動的,那麼只要點擊a,那麼頁面就會迅速跳轉到id=A的元素上

如今對咱們的頁面添加一些herfid

<div class="con">
    <!--聯繫人列表-->
    <div class="contacts" id="contacts">
        <dl id='A'>A</dt>
        <dt>a1</dt>
        <dt>a2</dt>
        <dl id='B'>B</dt>
        <dt>b1</dt>
        <dt>b2</dt>
        ...
    </div>
    <!--導航列表-->
    <div class="index" id="index">
        <a href='#A'>A</a>
        <a href='#B'>B</a>
    </div>
</div>

https://codepen.io/xboxyan/pe...

點擊右側的導航按鈕,頁面就能夠快速定位了

等等,好像還有些問題,當往回跳轉時,發現並無徹底展開,好比像調回A,結果雖然A標籤出來了,可是,A下面的列表卻沒有出來

20181016205557.png

這是什麼問題呢?

通過屢次的研究,發現是position:sticky搞的鬼!

當往上定位的時候,咱們經過href定位過去,定位的依據是到該元素第一次可見的位置,此時雖然該元素空壓機了,可是下面的元素沒有展現出來,因此就形成了這樣的問題

發現問題就要解決問題

快速定位效果修復

其實咱們想要定位的還能夠是A下面的第一個列表元素,可是又不能是該元素,由於若是是第一代元素,當跳轉的時候就會被上面的A標籤遮住。

因此咱們在二者之間再插入一個標籤,用於定位

以下,添加了<dl class="stikcy-fix"></dt>

<div class="contacts" id="contacts">
        <dl>A</dt>
        <dl class="stikcy-fix" id='A'></dt>
        <dt>a1</dt>
        <dt>a2</dt>
        <dl>B</dt>
        <dl class="stikcy-fix" id='B'></dl>
        <dt>b1</dt>
        <dt>b2</dt>
        ...
    </div>

若是直接放在這裏確定會佔空間,因此咱們把他向上位移,而後設置不可見,使該元素恰好覆蓋在原標籤位置

以下

.contacts .stikcy-fix{
    position: static;
    visibility: hidden;
    margin-top: -2em;
}

https://codepen.io/xboxyan/pe...

如今看看,是否是完美跳轉了?

其餘細節

一般咱們在選擇右側索引時,頁面中間會出現一個大寫的字母

20181017093614.png

這個若是用css實現也比較簡單,用到僞元素的content:attr()就能夠了,在以前的文章(用純css實現打星星效果)中也講到過

具體實現以下

.index a:active:after{
    content: attr(data-type);
    position: fixed;
    left: 50%;
    top: 50%;
    width: 100px;
    height: 100px;
    border-radius: 5px;
    text-align: center;
    line-height: 100px;
    font-size: 50px;
    transform: translate(-50%,-50%);
    background: rgba(0,0,0,.5);
}

這裏用到了content: attr(data-type),因此a上面要有一個data-type屬性

<!--導航列表-->
<div class="index" id="index">
    <a href='#A' data-type='A'>A</a>
    <a href='#B' data-type='B'>B</a>
</div>

其次,實際項目中,咱們須要用js來生成這些列表

假定咱們要求的數據以下

var data = [
        {
            'type':'A',
            'user':[
                {
                    name:'a1'
                },
                {
                    name:'a2'
                },
                {
                    name:'a3'
                },
                {
                    name:'a1'
                },
                {
                    name:'a2'
                },
                {
                    name:'a3'
                },
                {
                    name:'a3'
                },
                {
                    name:'a1'
                },
                {
                    name:'a2'
                },
                {
                    name:'a3'
                },
            ]
        },
        {
            'type':'B',
            'user':[
                {
                    name:'b1'
                },
                {
                    name:'b2'
                },
                {
                    name:'b3'
                },
                {
                    name:'b1'
                },
                {
                    name:'b2'
                },
                {
                    name:'b3'
                },
                {
                    name:'b3'
                },
                {
                    name:'b1'
                },
                {
                    name:'b2'
                },
                {
                    name:'b3'
                },
            ]
        },
        {
            'type':'C',
            'user':[
                {
                    name:'c1'
                },
                {
                    name:'c2'
                },
                {
                    name:'c3'
                },
                {
                    name:'c1'
                },
                {
                    name:'c2'
                },
                {
                    name:'c3'
                },
                {
                    name:'c3'
                },
                {
                    name:'c1'
                },
                {
                    name:'c2'
                },
                {
                    name:'c3'
                },
            ]
        },
        {
            'type':'D',
            'user':[
                {
                    name:'d1'
                },
                {
                    name:'d2'
                },
                {
                    name:'d3'
                },
                {
                    name:'d1'
                },
                {
                    name:'d2'
                },
                {
                    name:'d3'
                },
                {
                    name:'d3'
                },
                {
                    name:'d1'
                },
                {
                    name:'d2'
                },
                {
                    name:'d3'
                },
            ]
        },
        {
            'type':'E',
            'user':[
                {
                    name:'e1'
                },
                {
                    name:'e2'
                },
                {
                    name:'e3'
                },
                {
                    name:'e1'
                },
                {
                    name:'e2'
                },
                {
                    name:'e3'
                },
                {
                    name:'e3'
                },
                {
                    name:'e1'
                },
                {
                    name:'e2'
                },
                {
                    name:'e3'
                },
            ]
        }
    ]

這種格式的數據能夠要求後端返回,或者直接前端改造都行

而後對數據進行循環遍歷便可

var indexs = document.getElementById('index');
var contacts = document.getElementById('contacts');
var index_html = '';
var contacts_html = '';
data.forEach(el=>{
    contacts_html += '<dl><dt>'+el.type+'</dt><dt class="stikcy-fix" id='+el.type+'></dt>';
    index_html += '<a href="#'+el.type+'" data-type='+el.type+'>'+el.type+'</a>';
    el.user.forEach(d=>{
        contacts_html+='<dd>'+d.name+'</dd>';
    })
    contacts_html+='</dl>'
})
indexs.innerHTML = index_html;
contacts.innerHTML = contacts_html;

https://codepen.io/xboxyan/pe...

這部分js只是生成佈局,沒有任何功能上的邏輯

一些不足

雖然經過錨點實現列表的快速定位,可是此時瀏覽器的地址欄會加上#A這樣的標識,一很差看,二在使用瀏覽器默認的返回時會把這些標識所有走一遍,不太方便。

還有一個問題,在滾動列表的時候,無法作到右側索引當前類別高亮顯示,同時右側索引也不支持滑動快速定位。

這些細節問題也只能經過js來修復了。

不過要是一個簡單的小項目,沒那麼多要求的話,純css仍是能很好的適用的,性能上絕對要比經過js滾動監聽強上好多倍,並且引用方便,只要數據生成了就能夠直接使用^^

相關文章
相關標籤/搜索