|
|
|
|
|
水平滾動容器(或列表)不再將所有內(nèi)容堆疊在一起,而是成為一種常見的布局實踐,因為它有助于減少屏幕較小的設(shè)備的垂直空間。在本文中,我想探討 CSS Grid 的靈活性如何幫助實現(xiàn)水平滾動組件。
效果
整體布局
現(xiàn)在讓我們看看如何使用 CSS Grid 對其進行編碼。CSS Grid 的方便之處在于我們可以無縫控制元素之間的間距,而無需進一步計算。
對于整體布局,我們將使用一種簡單而強大的 CSS Grid 技術(shù):
.app {
display: grid;
grid-template-columns: 20px 1fr 20px;
}
.app > * {
grid-column: 2 / -2;
}
.app > .full {
grid-column: 1 / -1;
}
.app的任何直接子項都將被“容器化”,兩端有20px的間隙,使內(nèi)容遠離邊緣。如果一個子項配備了一個.full
類,它將跨越整個視口,而不會在側(cè)面有任何填充。
滾動容器
讓我們用六張卡片創(chuàng)建水平滾動容器,一次顯示兩張。由于我們希望水平滾動容器遵循整體布局,兩側(cè)都有填充,我們省略.full
類,可能會嘗試這樣的事情:
.hs {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(6, calc(50% - 40px));
grid-template-rows: minmax(150px, 1fr);
}
使用grid-template-columns我們可以設(shè)置我們希望每張卡片應(yīng)該占用多少空間——在這個例子中,卡片占據(jù)了 50% 的視口。當(dāng)減去邊距時,我們最終會看到第三張卡片在最后露出來。
然而——正如你可能已經(jīng)注意到的——卡片的兩端都被切斷了。請記住,當(dāng)我們滾動時,我們希望可滾動內(nèi)容在屏幕邊緣滑動。
因此,讓我們在容器中添加一個.full
類并彌補缺少的填充:
.hs {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(6, calc(50% - 40px));
grid-template-rows: minmax(150px, 1fr);
padding: 0 20px;
}
乍一看,似乎我們已經(jīng)達到了預(yù)期的效果,但是一旦滾動到最后,你會注意到?jīng)]有任何空間-因此不尊重整體布局。
你可能希望通過向最后一個元素添加一個邊距來處理它,如下所示:
.hs > li:last-child {
margin-right: 20px;
}
不幸的是,這也不起作用。那么我們該如何解決呢?
建議的解決方案
讓我們考慮一下我們所擁有的,一旦我們刪除了容器的填充:
.hs {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(6, calc(50% - 40px));
grid-template-rows: minmax(150px, 1fr);
}
如果我們在 grid-template-columns 的任一側(cè)添加一些空白作為填充,我們應(yīng)該能夠?qū)崿F(xiàn)我們想要的布局。
讓我們在兩端的網(wǎng)格列中添加 2 x 10 像素的空白區(qū)域。結(jié)合 10px 的 grid-gap 值,我們總共有 20px,因此遵循整體布局的填充。
.hs {
display: grid;
grid-gap: 10px;
grid-template-columns:
10px
repeat(6, calc(50% - 40px))
10px;
grid-template-rows: minmax(150px, 1fr);
}
為了不讓第一張卡片占據(jù)第一列 10px 的空間,我們在每一端引入空的偽元素,如下所示:
.hs::before,
.hs::after {
content: ‘’;
}
::before
和 ::after
元素非常適合網(wǎng)格列,因為它們會自動添加到水平滾動容器的開頭和結(jié)尾。值得慶幸的是,偽元素參與了網(wǎng)格。
現(xiàn)在我們正在實現(xiàn)我們在開始時概述的所有布局功能。
注意事項
這種技術(shù)的一個警告是你必須在grid-template-columns中指定固定數(shù)量的卡片:
grid-template-columns:
10px
repeat(6, calc(50% - 40px))
10px;
如果其中一個容器僅包含 4 張卡片,你將需要為該特定容器設(shè)置新的網(wǎng)格規(guī)則。這不是很靈活。
使其更靈活的一種方法是使用 Javascript 計算特定容器中的卡片數(shù)量,然后將此數(shù)字分配給 CSS 變量:
var root = document.documentElement;
const lists = document.querySelectorAll('.hs');
lists.forEach(el => {
const listItems = el.querySelectorAll('li');
const n = el.children.length;
el.style.setProperty('--total', n);
});
然后你可以使用網(wǎng)格模板列中的變量:
grid-template-columns:
10px
repeat(var(--total), calc(50% - 40px))
10px;
你也可以通過利用隱式網(wǎng)格完全省略 javascript(或 CSS 變量解決方案)。這樣,我們不需要計算我們需要的溢出列的數(shù)量,因為這是由瀏覽器為我們計算的。
為此,我們需要稍微不同地設(shè)置我們的代碼:
.hs {
...
grid-template-columns: 10px;
grid-auto-flow: column;
grid-auto-columns: calc(50% - var(--gutter) * 2);
...
...
.hs:before,
.hs:after {
content: '';
width: 10px;
}
我們?nèi)匀恍枰覀冏畛醯?10px 來補償填充;但是,其余的卡片現(xiàn)在由自動放置算法布局。不過,為了讓它工作,我們需要將自動流設(shè)置為“列”(默認為“行”)。
最后,我們需要確保 .hs:after(繼承其他卡片的大?。┱加玫目臻g不超過 10 像素。所以我們通過應(yīng)用固定寬度來限制偽元素的大小。
總結(jié)
本文介紹了如何用CSS Grid技術(shù)創(chuàng)建水平(橫向)滾動容器或列表(div、ul等),該文需要你對CSS Grid有一定的了解。
如果你不喜歡CSS Grid,那么你也完全可以用更加簡單傳統(tǒng)的CSS創(chuàng)建水平滾動列表,或者用JavaScript創(chuàng)建水平(橫向)滾動列表。
相關(guān)文章