|
|
|
|
|
水平滾動(dòng)容器(或列表)不再將所有內(nèi)容堆疊在一起,而是成為一種常見(jiàn)的布局實(shí)踐,因?yàn)樗兄跍p少屏幕較小的設(shè)備的垂直空間。在本文中,我想探討 CSS Grid 的靈活性如何幫助實(shí)現(xiàn)水平滾動(dòng)組件。
效果
整體布局
現(xiàn)在讓我們看看如何使用 CSS Grid 對(duì)其進(jìn)行編碼。CSS Grid 的方便之處在于我們可以無(wú)縫控制元素之間的間距,而無(wú)需進(jìn)一步計(jì)算。
對(duì)于整體布局,我們將使用一種簡(jiǎn)單而強(qiáng)大的 CSS Grid 技術(shù):
.app {
display: grid;
grid-template-columns: 20px 1fr 20px;
}
.app > * {
grid-column: 2 / -2;
}
.app > .full {
grid-column: 1 / -1;
}
.app的任何直接子項(xiàng)都將被“容器化”,兩端有20px的間隙,使內(nèi)容遠(yuǎn)離邊緣。如果一個(gè)子項(xiàng)配備了一個(gè).full
類(lèi),它將跨越整個(gè)視口,而不會(huì)在側(cè)面有任何填充。
滾動(dòng)容器
讓我們用六張卡片創(chuàng)建水平滾動(dòng)容器,一次顯示兩張。由于我們希望水平滾動(dòng)容器遵循整體布局,兩側(cè)都有填充,我們省略.full
類(lèi),可能會(huì)嘗試這樣的事情:
.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)該占用多少空間——在這個(gè)例子中,卡片占據(jù)了 50% 的視口。當(dāng)減去邊距時(shí),我們最終會(huì)看到第三張卡片在最后露出來(lái)。
然而——正如你可能已經(jīng)注意到的——卡片的兩端都被切斷了。請(qǐng)記住,當(dāng)我們滾動(dòng)時(shí),我們希望可滾動(dòng)內(nèi)容在屏幕邊緣滑動(dòng)。
因此,讓我們?cè)谌萜髦刑砑右粋€(gè).full
類(lèi)并彌補(bǔ)缺少的填充:
.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)達(dá)到了預(yù)期的效果,但是一旦滾動(dòng)到最后,你會(huì)注意到?jīng)]有任何空間-因此不尊重整體布局。
你可能希望通過(guò)向最后一個(gè)元素添加一個(gè)邊距來(lái)處理它,如下所示:
.hs > li:last-child {
margin-right: 20px;
}
不幸的是,這也不起作用。那么我們?cè)撊绾谓鉀Q呢?
建議的解決方案
讓我們考慮一下我們所擁有的,一旦我們刪除了容器的填充:
.hs {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(6, calc(50% - 40px));
grid-template-rows: minmax(150px, 1fr);
}
如果我們?cè)?grid-template-columns 的任一側(cè)添加一些空白作為填充,我們應(yīng)該能夠?qū)崿F(xiàn)我們想要的布局。
讓我們?cè)趦啥说木W(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 的空間,我們?cè)诿恳欢艘肟盏膫卧?,如下所示?/p>
.hs::before,
.hs::after {
content: ‘’;
}
::before
和 ::after
元素非常適合網(wǎng)格列,因?yàn)樗鼈儠?huì)自動(dòng)添加到水平滾動(dòng)容器的開(kāi)頭和結(jié)尾。值得慶幸的是,偽元素參與了網(wǎng)格。
現(xiàn)在我們正在實(shí)現(xiàn)我們?cè)陂_(kāi)始時(shí)概述的所有布局功能。
注意事項(xiàng)
這種技術(shù)的一個(gè)警告是你必須在grid-template-columns中指定固定數(shù)量的卡片:
grid-template-columns:
10px
repeat(6, calc(50% - 40px))
10px;
如果其中一個(gè)容器僅包含 4 張卡片,你將需要為該特定容器設(shè)置新的網(wǎng)格規(guī)則。這不是很靈活。
使其更靈活的一種方法是使用 Javascript 計(jì)算特定容器中的卡片數(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;
你也可以通過(guò)利用隱式網(wǎng)格完全省略 javascript(或 CSS 變量解決方案)。這樣,我們不需要計(jì)算我們需要的溢出列的數(shù)量,因?yàn)檫@是由瀏覽器為我們計(jì)算的。
為此,我們需要稍微不同地設(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 來(lái)補(bǔ)償填充;但是,其余的卡片現(xiàn)在由自動(dòng)放置算法布局。不過(guò),為了讓它工作,我們需要將自動(dòng)流設(shè)置為“列”(默認(rèn)為“行”)。
最后,我們需要確保 .hs:after(繼承其他卡片的大?。┱加玫目臻g不超過(guò) 10 像素。所以我們通過(guò)應(yīng)用固定寬度來(lái)限制偽元素的大小。
總結(jié)
本文介紹了如何用CSS Grid技術(shù)創(chuàng)建水平(橫向)滾動(dòng)容器或列表(div、ul等),該文需要你對(duì)CSS Grid有一定的了解。
如果你不喜歡CSS Grid,那么你也完全可以用更加簡(jiǎn)單傳統(tǒng)的CSS創(chuàng)建水平滾動(dòng)列表,或者用JavaScript創(chuàng)建水平(橫向)滾動(dòng)列表。
相關(guān)文章