翻轉(zhuǎn)再翻轉(zhuǎn)!有意思的水平橫向溢出滾動(dòng)
最近接到一個(gè)很有意思的需求,能否做到當(dāng)內(nèi)容橫向溢出時(shí),依然能夠使用鼠標(biāo)滾輪對(duì)內(nèi)容進(jìn)行滾動(dòng)的方法。
什么意思呢?來(lái)看看這么一種情況:
我們有一個(gè)垂直方向溢出滾動(dòng)的容器,以及一個(gè)水平方向溢出滾動(dòng)的容器:
如果使用的是非觸控板(大部分用戶(hù)沒(méi)有觸控板),而是使用鼠標(biāo)來(lái)進(jìn)行操作,會(huì)發(fā)現(xiàn),這兩個(gè)容器中,只有垂直方向溢出滾動(dòng)的容器,是可以響應(yīng)鼠標(biāo)滾輪的:
- 垂直方向溢出滾動(dòng)的容器,正常響應(yīng)鼠標(biāo)滾輪,可滾動(dòng)內(nèi)容。
- 水平方向溢出滾動(dòng)的容器,不會(huì)響應(yīng)鼠標(biāo)滾輪,不可滾動(dòng)內(nèi)容。
那么,這里可能就是一個(gè)用戶(hù)痛點(diǎn)。
如果在一些特定場(chǎng)景下,確實(shí)有橫向滾動(dòng)的內(nèi)容,譬如橫向的圖片內(nèi)容展示等。又想使用鼠標(biāo)滾輪對(duì)內(nèi)容進(jìn)行滾動(dòng),能否做到呢?
那是必須的,本文就將介紹一種可能可行的技巧,在特定場(chǎng)景下在水平方向溢出滾動(dòng)的容器,依然可以用鼠標(biāo)滾輪進(jìn)行滾動(dòng)。
旋轉(zhuǎn)大法
是的,既然只有垂直方向的溢出,才能響應(yīng)滾輪操作。那我們不妨從這個(gè)角度入手。
首先實(shí)現(xiàn)一個(gè)垂直方向的溢出:
<div class="g-scroll">
<div class="g-pesudo"></div>
</div>
.g-scroll {
width: 200px;
height: 200px;
border: 1px solid #f00;
}
.g-pesudo {
width: 200px;
height: 400px;
background: linear-gradient(rgba(122, 122, 50, .3), rgba(20, 200, 150, .3))
}
``
大概是這樣:

好,加上 `overflow: hidden`,就會(huì)變成這樣:
```CSS
.g-scroll {
overflow: scroll;
}
既然只有垂直方向的溢出,才能響應(yīng)滾輪操作。要想變成水平方向的,我們只需要給容器旋轉(zhuǎn) 90° 不就行了嗎?
好像有點(diǎn)道理,我們來(lái)嘗試下:
.g-scroll {
width: 200px;
height: 200px;
box-sizing: border-box;
transform: rotate(-90deg);
overflow: scroll;
}
看看效果:
這樣,原本豎直的容器,就變成了水平的容器,圖中鼠標(biāo)沒(méi)有在滾動(dòng)條上容器的運(yùn)動(dòng)就是通過(guò)滾輪實(shí)現(xiàn)的。
當(dāng)然,這樣還有個(gè)非常嚴(yán)重的問(wèn)題,如果容器內(nèi)存在內(nèi)容,那么就變成了這樣:
Oh,由于容器整體旋轉(zhuǎn)了 90°,里面的內(nèi)容當(dāng)然也一起發(fā)生了旋轉(zhuǎn)。我們需要解決這個(gè)問(wèn)題。
內(nèi)容反向旋轉(zhuǎn) 90°,修復(fù)視角
這個(gè)也好解決,我們只需要重新構(gòu)造下 DOM,將原本的內(nèi)容再反向旋轉(zhuǎn) 90° 一次。
當(dāng)然,需要同時(shí)處理好旋轉(zhuǎn)中心。
整個(gè)結(jié)構(gòu)變成了這樣:
<div class="g-scroll">
<div class="g-pesudo"></div>
<div class="g-content">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolorum quis ipsum officiis placeat ipsa sit ad incidunt similique, consequuntur earum architecto recusandae veritatis et illo, illum quae nulla minus rerum?
</div>
</div>
我們將實(shí)際裝有了文字內(nèi)容的 DOM 提取出來(lái)成一個(gè)單獨(dú)的 DOM,與 g-pesudo 同級(jí)。
我們實(shí)際觸發(fā)滾動(dòng)操作的實(shí)際是 g-pesudo 的變化,我們只需要將內(nèi)容通過(guò)再一次旋轉(zhuǎn),完美疊加在原本的容器之上即可:
.g-scroll {
position: relative;
width: 200px;
height: 200px;
transform-origin: 100% 0;
transform: rotate(-90deg);
overflow: scroll;
}
.g-pesudo {
width: 200px;
height: 400px;
background: linear-gradient(rgba(122, 122, 50, .3), rgba(20, 200, 150, .3));
}
.g-content {
position: absolute;
top: 0;
left: 200px;
width: 400px;
height: 200px;
transform-origin: 0 0;
border: 1px solid #000;
transform: rotate(90deg);
}
什么意思呢。通過(guò)定位,我們將 g-content 高寬設(shè)置為容器旋轉(zhuǎn)后,滾動(dòng)內(nèi)容的 DOM 實(shí)際表現(xiàn)為的高寬。
并且,通過(guò)設(shè)定以左下角為旋轉(zhuǎn)中心 transform-origin: 0 0,再經(jīng)過(guò)一次旋轉(zhuǎn),將滾動(dòng)容器,和內(nèi)容疊加在一起:
好,經(jīng)過(guò)這一系列較為復(fù)雜的操作,我們就實(shí)現(xiàn)了內(nèi)容適配旋轉(zhuǎn),給容器加上 overflow: scroll,一切表現(xiàn)正常,我們實(shí)現(xiàn)了橫向滾動(dòng)溢出,鼠標(biāo)滾輪依舊生效!
完整的代碼,你可以戳:CodePen Demo -- CSS-Only Horizontal Parallax Gallery[1]。
隱藏滾動(dòng)條
當(dāng)然,有個(gè)問(wèn)題,這樣滾動(dòng)條就穿幫了。
這里,在現(xiàn)代瀏覽器,我們可以通過(guò) ::-webkit-scrollbar 相關(guān) CSS 隱藏掉整個(gè)滾動(dòng)條:
/* hide scrollbar */
::scrollbar {
width: 1px;
height: 1px;
}
::scrollbar-button {
width: 1px;
height: 1px;
}
這樣,整個(gè)效果,就感受不到滾動(dòng)條的存在,可以直接使用滾輪進(jìn)行控制:
上述操作都在鼠標(biāo)滾輪下完成。
其他用途場(chǎng)景
這個(gè)技巧,只有特定的一些場(chǎng)景才適用。
如果內(nèi)部的 DOM 復(fù)雜一點(diǎn),整體改造的成本就非常高了,不太適合。
這里再給另外一個(gè)用這個(gè)技巧實(shí)現(xiàn)的 DEMO,一個(gè)橫向 3D 純 CSS 的視差效果,使用鼠標(biāo)滾輪控制頁(yè)面橫向滾動(dòng):
感興趣可以自行研究下源碼,整體的技巧與上述闡述的類(lèi)似,容器一次旋轉(zhuǎn),內(nèi)容二次反向旋轉(zhuǎn)即可。
CodePen Demo -- CSS-Only Horizontal Parallax Gallery By Paulina Hetman[2]。
最后
好了,本文到此結(jié)束,希望對(duì)你有幫助 :)
參考資料
[1]CodePen Demo -- CSS-Only Horizontal Parallax Gallery: https://codepen.io/Chokcoco/pen/PoRLpGO。
[2]CodePen Demo -- CSS-Only Horizontal Parallax Gallery By Paulina Hetman: https://codepen.io/pehaa/pen/zYxbxQg。