我希望我的网格像这样垂直填充:
1 4 7
2 5 8
3 6 9
... arbitrary number of additional rows.
相反,它会像这样水平填充:
1 2 3
4 5 6
7 8 9
我想指定网格中的列数,而不是行数。
这就是我的div使用内联CSS样式的样子:
<div style="display:grid; grid-template-columns:1fr 1fr 1fr;">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
</div>
我的网格宽3列是很重要的,但我希望项目按列填充,而不是按行填充。 CSS Grid中有可能吗?我已经阅读了这个https://css-tricks.com/snippets/css/complete-guide-grid/,但没有看到关于订单的任何内容。
CSS Flexbox有flex-direction
,是不是有类似CSS Grid的属性?
答案 0 :(得分:19)
对于根据需要创建新列并且未定义行的垂直流动网格,请考虑使用CSS Multi-Column Layout(example)。 CSS网格布局(至少当前实现 - Level 1)无法执行此任务。这就是问题所在:
在CSS网格布局中,grid-auto-flow
和grid-template-rows
/ grid-template-columns
属性之间存在反比关系。
更具体地说,通过定义grid-auto-flow: row
(默认设置)和grid-template-columns
,网格项在水平方向上流畅地运行,并根据需要自动创建新行。这个概念在问题的代码中说明。
#container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-auto-flow: row;
}
&#13;
<div id="container">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
</div>
&#13;
但是,切换到grid-template-rows
后,网格项会堆叠在一列中。
#container {
display: grid;
grid-template-rows: 1fr 1fr 1fr;
grid-auto-flow: row;
}
&#13;
<div id="container">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
</div>
&#13;
没有使用grid-auto-flow: row
和grid-template-rows
自动创建列。必须定义grid-template-columns
(因此,与grid-auto-flow
成反比关系。)
#container {
display: grid;
grid-template-rows: 1fr 1fr 1fr;
grid-template-columns: 1fr 1fr 1fr;
grid-auto-flow: row;
}
&#13;
<div id="container">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
</div>
&#13;
在相反的情况下,情况也是如此。
在定义了grid-auto-flow: column
和grid-template-rows
的情况下,网格项在垂直方向上流畅地运行,并根据需要自动创建新列。
#container {
display: grid;
grid-template-rows: 1fr 1fr 1fr;
grid-auto-flow: column;
}
&#13;
<div id="container">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
</div>
&#13;
但是,切换到grid-template-columns
后,网格项会堆叠在一行中。 (这是大多数人提出的问题,包括在这个问题中。)
#container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-auto-flow: column;
}
&#13;
<div id="container">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
</div>
&#13;
没有自动创建行。这需要定义grid-template-rows
。 (这是最常提供的解决方案,但通常会被拒绝,因为布局的行数可变。)
#container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
grid-auto-flow: column;
}
&#13;
<div id="container">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
</div>
&#13;
因此,请考虑multi-column layout solution,如上所述。
答案 1 :(得分:11)
另一种选择是删除CSS Grid并使用CSS Columns,它完全符合您的要求,并且还有更好的浏览器支持。
.csscolumn {
-webkit-column-count: 3; /* Chrome, Safari, Opera */
-moz-column-count: 3; /* Firefox */
column-count: 3;
}
/* styling for this demo */
.csscolumn {
width: 50%;
}
.csscolumn + .csscolumn {
margin-top: 10px;
padding-top: 10px;
border-top: 1px solid;
}
&#13;
<div class="csscolumn">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
</div>
<div class="csscolumn">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</div>
<div class="csscolumn">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
</div>
&#13;
答案 2 :(得分:5)
作为一项技术练习而非实际解决方案,您可以根据项目数量以某种方式使用特定样式获得结果
让我们看看它是如何运作的:
.item:first-child:nth-last-child(n+4):nth-last-child(-n + 6) ~ .item:nth-child(n+3)
第一个选择器
.item:first-child:nth-last-child(n+4):nth-last-child(-n + 6)
是活动的,我们的列表有4到6个元素。在这种情况下,某些项目将处于第一个条件和第二个条件中。
在这种情况下,我们希望第一列中有2个项目。使用
定位剩余的项目(从第三个开始)~ .item:nth-child(n+3)
并将它们放在第二列。类似的规则,现在是第5个及以后的
~ .item:nth-child(n+5)
将其他项目放在第三列中。这两个规则具有相同的优先级,并且针对最后一项,因此它们按此顺序显示至关重要。
我们需要重复类似的规则,直到可以存在的最大项目数量(可能是预处理器的工作)
var elements = 5;
function add () {
var ctn = document.getElementById("container");
var ele = document.createElement("div");
elements ++;
ele.innerHTML = elements;
ele.className = "item";
ctn.appendChild (ele);
}
#container {
width: 90%;
border: solid 1px red;
display: grid;
grid-template-rows: 33% 33% 33%;
grid-auto-flow: column dense;
}
.item {
width: 90%;
height: 80px;
background-color: lightgreen;
margin: 10px;
grid-column: 1;
}
.item:first-child:nth-last-child(n+4):nth-last-child(-n + 6) ~ .item:nth-child(n+3) {
background-color: yellow;
grid-column: 2;
}
.item:first-child:nth-last-child(n+4):nth-last-child(-n + 6) ~ .item:nth-child(n+5) {
background-color: tomato;
grid-column: 3;
}
.item:first-child:nth-last-child(n+7):nth-last-child(-n + 9) ~ .item:nth-child(n+4) {
background-color: burlywood;
grid-column: 2;
}
.item:first-child:nth-last-child(n+7):nth-last-child(-n + 9) ~ .item:nth-child(n+7) {
background-color: blueviolet;
grid-column: 3;
}
.item:first-child:nth-last-child(n+10):nth-last-child(-n + 12) ~ .item:nth-child(n+5) {
background-color: darkcyan;
grid-column: 2;
}
.item:first-child:nth-last-child(n+10):nth-last-child(-n + 12) ~ .item:nth-child(n+9) {
background-color: chartreuse;
grid-column: 3;
}
.item:first-child:nth-last-child(n+13):nth-last-child(-n + 15) ~ .item:nth-child(n+6) {
background-color: yellow;
grid-column: 2;
}
.item:first-child:nth-last-child(n+13):nth-last-child(-n + 15) ~ .item:nth-child(n+11) {
background-color: tomato;
grid-column: 3;
}
<button onclick="add()">Add</button>
<div id="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
</div>
答案 3 :(得分:2)
我见过的最简单的方法如下:
.grid {
display: grid;
grid-auto-flow: column;
grid-gap: 1px;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(5, auto);
}
<div class="grid">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
<div>11</div>
<div>12</div>
<div>13</div>
</div>
答案 4 :(得分:0)
这是一种基于 CSS Grid 的方法,使用javascript和CSSOM插入一对:
transform: translate(x, y)
规则生成样式表。
两个转换规则(仅两个,基于网格 3列宽替换原始单列网格的下部元素,向上移动元素在右边。
因此,您可以向单列网格添加任意数量的元素,并且脚本将始终调整网格,使其具有三个大小相等的列。
如果列的大小不能完全相同,则较高的列将始终是第一列和/或第二列(从不是最右边的第三列)。
工作示例(9个网格单位):
var numberOfColumns = 3;
document.head.appendChild(document.createElement('style'));
var newStyles = document.styleSheets[(document.styleSheets.length - 1)];
var myGrid = document.getElementsByClassName('my-grid')[0];
var myGridUnits = myGrid.getElementsByTagName('div');
var tallColumn = Math.ceil(myGridUnits.length / numberOfColumns);
var shortColumn = Math.floor(myGridUnits.length / numberOfColumns);
var nextUnit = 1;
var unitsRemaining = myGridUnits.length;
var xTranslate, yTranslate;
var columns = [];
for (var i = 0; i < (numberOfColumns - 1); i++) {
if (unitsRemaining % shortColumn === 0) {
columns.push(shortColumn);
}
else {
columns.push(tallColumn);
}
nextUnit += columns[(columns.length - 1)];
unitsRemaining -= columns[(columns.length - 1)];
xTranslate = ((i + 1) * 48);
yTranslate = 0;
columns.forEach(function(columnHeight){yTranslate += (columnHeight * 48);});
newStyles.insertRule('.my-grid div:nth-of-type(n+' + nextUnit + ') {transform: translate(' + xTranslate + 'px, ' + (0 - (yTranslate)) + 'px);}', newStyles.cssRules.length);
}
&#13;
.my-grid {
display: inline-grid;
grid-row-gap: 6px;
}
.my-grid div {
width: 40px;
height: 40px;
line-height: 40px;
text-align: center;
border: 1px solid rgb(127, 127, 127);
}
&#13;
<div class="my-grid">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
</div>
&#13;
工作示例(10个网格单位):
var numberOfColumns = 3;
document.head.appendChild(document.createElement('style'));
var newStyles = document.styleSheets[(document.styleSheets.length - 1)];
var myGrid = document.getElementsByClassName('my-grid')[0];
var myGridUnits = myGrid.getElementsByTagName('div');
var tallColumn = Math.ceil(myGridUnits.length / numberOfColumns);
var shortColumn = Math.floor(myGridUnits.length / numberOfColumns);
var nextUnit = 1;
var unitsRemaining = myGridUnits.length;
var xTranslate, yTranslate;
var columns = [];
for (var i = 0; i < (numberOfColumns - 1); i++) {
if (unitsRemaining % shortColumn === 0) {
columns.push(shortColumn);
}
else {
columns.push(tallColumn);
}
nextUnit += columns[(columns.length - 1)];
unitsRemaining -= columns[(columns.length - 1)];
xTranslate = ((i + 1) * 48);
yTranslate = 0;
columns.forEach(function(columnHeight){yTranslate += (columnHeight * 48);});
newStyles.insertRule('.my-grid div:nth-of-type(n+' + nextUnit + ') {transform: translate(' + xTranslate + 'px, ' + (0 - (yTranslate)) + 'px);}', newStyles.cssRules.length);
}
&#13;
.my-grid {
display: inline-grid;
grid-row-gap: 6px;
}
.my-grid div {
width: 40px;
height: 40px;
line-height: 40px;
text-align: center;
border: 1px solid rgb(127, 127, 127);
}
&#13;
<div class="my-grid">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
</div>
&#13;
工作示例(11个网格单位):
var numberOfColumns = 3;
document.head.appendChild(document.createElement('style'));
var newStyles = document.styleSheets[(document.styleSheets.length - 1)];
var myGrid = document.getElementsByClassName('my-grid')[0];
var myGridUnits = myGrid.getElementsByTagName('div');
var tallColumn = Math.ceil(myGridUnits.length / numberOfColumns);
var shortColumn = Math.floor(myGridUnits.length / numberOfColumns);
var nextUnit = 1;
var unitsRemaining = myGridUnits.length;
var xTranslate, yTranslate;
var columns = [];
for (var i = 0; i < (numberOfColumns - 1); i++) {
if (unitsRemaining % shortColumn === 0) {
columns.push(shortColumn);
}
else {
columns.push(tallColumn);
}
nextUnit += columns[(columns.length - 1)];
unitsRemaining -= columns[(columns.length - 1)];
xTranslate = ((i + 1) * 48);
yTranslate = 0;
columns.forEach(function(columnHeight){yTranslate += (columnHeight * 48);});
newStyles.insertRule('.my-grid div:nth-of-type(n+' + nextUnit + ') {transform: translate(' + xTranslate + 'px, ' + (0 - (yTranslate)) + 'px);}', newStyles.cssRules.length);
}
&#13;
.my-grid {
display: inline-grid;
grid-row-gap: 6px;
}
.my-grid div {
width: 40px;
height: 40px;
line-height: 40px;
text-align: center;
border: 1px solid rgb(127, 127, 127);
}
&#13;
<div class="my-grid">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
<div>11</div>
</div>
&#13;
工作示例(14个网格单位):
var numberOfColumns = 3;
document.head.appendChild(document.createElement('style'));
var newStyles = document.styleSheets[(document.styleSheets.length - 1)];
var myGrid = document.getElementsByClassName('my-grid')[0];
var myGridUnits = myGrid.getElementsByTagName('div');
var tallColumn = Math.ceil(myGridUnits.length / numberOfColumns);
var shortColumn = Math.floor(myGridUnits.length / numberOfColumns);
var nextUnit = 1;
var unitsRemaining = myGridUnits.length;
var xTranslate, yTranslate;
var columns = [];
for (var i = 0; i < (numberOfColumns - 1); i++) {
if (unitsRemaining % shortColumn === 0) {
columns.push(shortColumn);
}
else {
columns.push(tallColumn);
}
nextUnit += columns[(columns.length - 1)];
unitsRemaining -= columns[(columns.length - 1)];
xTranslate = ((i + 1) * 48);
yTranslate = 0;
columns.forEach(function(columnHeight){yTranslate += (columnHeight * 48);});
newStyles.insertRule('.my-grid div:nth-of-type(n+' + nextUnit + ') {transform: translate(' + xTranslate + 'px, ' + (0 - (yTranslate)) + 'px);}', newStyles.cssRules.length);
}
&#13;
.my-grid {
display: inline-grid;
grid-row-gap: 6px;
}
.my-grid div {
width: 40px;
height: 40px;
line-height: 40px;
text-align: center;
border: 1px solid rgb(127, 127, 127);
}
&#13;
<div class="my-grid">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
<div>11</div>
<div>12</div>
<div>13</div>
<div>14</div>
</div>
&#13;