我正在寻找一种实现这种效果的方法:
在移动版式上,元素在列中一个接一个地放置:
但是,在桌面布局中,元素放置在两列中,一列中包含奇数元素,另一列中包含偶数元素。列相对于彼此垂直移动:
我想知道是否只有CSS方式才能实现此定位。如果只有一种说法,例如nth-child(n+1)
将跨越第1和2行,而`nth-child(2n)将跨越第2和3行,以此类推,那么CSS网格将变得非常接近。但是我不确定CSS网格是否可以做到这一点。您也许知道这样做的方法吗?
更新:我猜想这是我所想到的非常粗略的CSS近似值,使用内联代码块:https://codepen.io/anon/pen/JwXVox。我欢迎更好的技术。
答案 0 :(得分:2)
大概,您知道如何制作移动版本,以及如何使用@media
来区分不同的屏幕尺寸。
我不完全理解“跨行1和2”的意思,但是您不必使用网格布局。好的老式内联块在这里可以正常工作。您的近似近似值是粗糙的,仅是因为您的余量值是粗略估计的,而不是因为您使用的技术不足以执行您想要的操作。
这就是我放置.grid-element
元素的位置(它对我来说看起来很漂亮;也许它与您想要的足够接近,可以对其进行微调):
您可以尝试使用不同的边距值来查看其效果。但基本上,一旦将它们并排设置,就将第二个向下推。这样可以正确定位第二个和第一个元素,但随后的所有元素也都会下降。因此,我们希望将负数的偶数备份增加。但是,我们不想提高第一个,因为它从未被降低。因此,我们使用nth-child(2n+3)
(即,每个第二个元素以三个开头)选择器将其排除。这等效于使用nth-child(odd):not(:first-child)
。
function fillGrid() {
const container = document.querySelector('.container');
const times = [...new Array(10)];
times.forEach(() => {
const element = document.createElement('div');
element.classList.add('grid-element');
container.appendChild(element);
});
}
fillGrid()
.container {
width: 60%;
margin: auto;
background: papayawhip;
padding-bottom: 60px;
}
.grid-element {
display: inline-block;
height: 50px;
background: green;
vertical-align: middle;
width: 48%;
margin: 0 1% 10px;
}
.grid-element:nth-child(2) {
margin-top: 60px;
}
.grid-element:nth-child(2n+3) {
margin-top: -60px;
}
<div class="container">
</div>
编辑:使用CSS网格获得相同的结果
在评论中我们进行了交谈之后,我尝试了position:grid
,以查看是否可以找到一种方法。我必须添加一行javascript(或编写一堆相当繁琐的CSS)才能完成此操作,但效果似乎不错。
我只是将行高设置为25%,然后在您的javascript中添加一行,以使每行加粗两行,并从上一个元素开始将其向下一行。
function fillGrid() {
const container = document.querySelector('.container');
const times = [...new Array(10)];
times.forEach((e, index) => {
const element = document.createElement('div');
element.classList.add('grid-element');
//added the line below to size and position the elements
element.setAttribute("style", "grid-row-start: " + (index + 1) + "; grid-row-end: " + (index + 3) + ";");
element.textContent = index + 1; //also put a number in each box
container.appendChild(element);
});
}
fillGrid()
.container {
display: grid;
grid-gap: 5px;
grid-template-columns: repeat(2, 1fr);
grid-auto-rows: 25px;
width: 60%;
margin: auto;
background: papayawhip;
}
.grid-element {
background: green;
color: white;
}
<div class="container">
</div>
答案 1 :(得分:2)
您可以使用 Flexbox ,calc()
功能,:nth-child()
,选择器,{{1} } 伪类,当然还有:not()
查询:
@media
.flex {
display: flex; /* displays flex-items (children) inline */
flex-wrap: wrap; /* enables their wrapping */
}
.flex > div {
flex-basis: calc(50% - 10px); /* initial width set to 50% of the parent's - left & right margins */
height: 100px;
margin: 0 5px; /* preferably top & bottom margins set to zero to keep calculations simple */
border: 1px solid;
box-sizing: border-box; /* because of the borders, also recommended in general */
}
.flex > div:nth-child(2){
margin-top: 55px; /* half of divs height + half of the desired gap between them; modification affects all but the first div */
}
.flex > div:nth-child(odd):not(:first-child){
margin-top: -45px; /* - half of divs height + half of the desired gap between them, so in this case the gap is 10px (2 x 5px); modification affects all but the first odd div (if ofc. modification is "") */
}
.flex > div:nth-child(even):not(:nth-child(2)){
margin-top: 10px; /* gap size; modification affects all but the first three divs */
}
@media (max-width: 600px){
.flex {flex-direction: column} /* stacks flex-items vertically */
.flex > div {flex-basis: auto} /* initial width set to default or 100% */
.flex > div:not(:first-child) {margin-top: 10px !important}
}
答案 2 :(得分:1)
一种float
方法
.container {
width: 250px;
margin: 0 auto;
}
.item {
width: 100px;
height: 100px;
border: 1px solid black;
margin-top: calc(100px/3);
}
.item:first-child {
margin-top: 0;
}
@media (min-width: 400px) {
.item:nth-child(even) {
float: right;
margin-top: calc(-100px/3);
}
}
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>