有意思的水平橫向溢位捲動

2022-09-07 12:02:06

最近接到一個很有意思的需求,能否做到當內容橫向溢位時,依然能夠使用滑鼠滾輪對內容進行卷動的方法

什麼意思呢?來看看這麼一種情況:

我們有一個垂直方向溢位捲動的容器,以及一個水平方向溢位捲動的容器:

如果使用的是非觸控板(大部分使用者沒有觸控板),而是使用滑鼠來進行操作,會發現,這兩個容器中,只有垂直方向溢位捲動的容器,是可以響應滑鼠滾輪的:

  1. 垂直方向溢位捲動的容器,正常響應滑鼠滾輪,可捲動內容
  2. 水平方向溢位捲動的容器,不會響應滑鼠滾輪,不可捲動內容

那麼,這裡可能就是一個使用者痛點。

如果在一些特定場景下,確實有橫向捲動的內容,譬如橫向的圖片內容展示等。又想使用滑鼠滾輪對內容進行卷動,能否做到呢?

那是必須的,本文就將介紹一種可能可行的技巧,在特定場景下在水平方向溢位捲動的容器,依然可以用滑鼠滾輪進行卷動。

旋轉大法

是的,既然只有垂直方向的溢位,才能響應滾輪操作。那我們不妨從這個角度入手。

首先實現一個垂直方向的溢位:

<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,就會變成這樣:

.g-scroll {
    overflow: scroll;
}

既然只有垂直方向的溢位,才能響應滾輪操作。要想變成水平方向的,我們只需要給容器旋轉 90° 不就行了嗎?

好像有點道理,我們來嘗試下:

.g-scroll {
    width: 200px;
    height: 200px;
    box-sizing: border-box;
    transform: rotate(-90deg);
    overflow: scroll;
}

看看效果:

這樣,原本豎直的容器,就變成了水平的容器,圖中滑鼠沒有在卷軸上容器的運動就是通過滾輪實現的。

當然,這樣還有個非常嚴重的問題,如果容器記憶體在內容,那麼就變成了這樣:

Oh,由於容器整體旋轉了 90°,裡面的內容當然也一起發生了旋轉。我們需要解決這個問題。

內容反向旋轉 90°,修復視角

這個也好解決,我們只需要重新構造下 DOM,將原本的內容再反向旋轉 90° 一次。

當然,需要同時處理好旋轉中心。

整個結構變成了這樣:

<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>

我們將實際裝有了文字內容的 DOM 提取出來成一個單獨的 DOM,與 g-pesudo 同級。

我們實際觸發捲動操作的實際是 g-pesudo 的變化,我們只需要將內容通過再一次旋轉,完美疊加在原本的容器之上即可:

.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);
}

什麼意思呢。通過定位,我們將 g-content 高寬設定為容器旋轉後,捲動內容的 DOM 實際表現為的高寬。

並且,通過設定以左下角為旋轉中心 transform-origin: 0 0,再經過一次旋轉,將捲動容器,和內容疊加在一起:

好,經過這一系列較為複雜的操作,我們就實現了內容適配旋轉,給容器加上 overflow: scroll,一切表現正常,我們實現了橫向捲動溢位,滑鼠滾輪依舊生效!

完整的程式碼,你可以戳:CodePen Demo -- CSS-Only Horizontal Parallax Gallery

隱藏卷軸

當然,有個問題,這樣卷軸就穿幫了。

這裡,在現代瀏覽器,我們可以通過 ::-webkit-scrollbar 相關 CSS 隱藏掉整個卷軸:

/* hide scrollbar */
::-webkit-scrollbar {
  width: 1px;
  height: 1px;
}
::-webkit-scrollbar-button {
  width: 1px;
  height: 1px;
}

這樣,整個效果,就感受不到卷軸的存在,可以直接使用滾輪進行控制:

上述操作都在滑鼠滾輪下完成。

其他用途場景

這個技巧,只有特定的一些場景才適用。

如果內部的 DOM 複雜一點,整體改造的成本就非常高了,不太適合。

這裡再給另外一個用這個技巧實現的 DEMO,一個橫向 3D 純 CSS 的視差效果,使用滑鼠滾輪控制頁面橫向捲動:

感興趣可以自行研究下原始碼,整體的技巧與上述闡述的類似,容器一次旋轉,內容二次反向旋轉即可。

CodePen Demo -- CSS-Only Horizontal Parallax Gallery By Paulina Hetman

最後

好了,本文到此結束,希望對你有幫助