在响应式布局中每隔 n 行偏移一次

Posted

技术标签:

【中文标题】在响应式布局中每隔 n 行偏移一次【英文标题】:Offset every nth row inside a responsive layout 【发布时间】:2016-04-13 06:49:24 【问题描述】:

我想仅在 html 和 CSS 中重建一种模式:

正如我想象的那样,我需要一组元素(此处显示为点),这些元素彼此相邻并具有特定的边距。然后我可以尝试为每个点的第 n 个实例添加更大的边距,它开始一个新行,以抵消它所在的行。我在这里创建了一个示例:

wrapper 
  width: 100%;

.dot 
  width: 150px;
  height: 150px;
  margin: 15px;
  border-radius: 50%;
  display: inline-block;
  background-color: #999;

.wrapper .dot:nth-child(4n) 
  margin-left: 100px;
  background-color: #dd77dd;
<div class="wrapper">
  <div class="dot">Element 1</div>
  <div class="dot">Element 2</div>
  <div class="dot">Element 3</div>
  <div class="dot">Element 4</div>
  <div class="dot">Element 5</div>
  <div class="dot">Element 6</div>
</div>

你也可以在这个小提琴中编辑它: https://jsfiddle.net/jessicajordan/j8238oo6/8/

此设置对于固定宽度的布局非常有效,例如当包含点元素的.wrapper 容器具有预定义的固定宽度时。 但是,我想让容器宽度响应(例如将其设置为 100% 宽度并使其宽度可根据视口大小调整),这意味着点的行可以包含不同数量的点元素,具体取决于.wrapper 容器。因此,开始新行的点元素应该通过使用比其他点更大的边距来为其添加偏移量,每次.wrapper 容器大小发生变化时都会是不同的。

如果仅在 HTML + CSS 中可行:如何为每第二行元素添加偏移量并在不同的容器大小中保留此布局?顺便提一下:点元素本身应该有一个固定的宽度,并且不应该随着.wrapper容器的大小而缩放。

【问题讨论】:

是否有固定点数或最大点数? 好问题 - 在我的设置中,它永远不会超过 30 个点。虽然目前还没有关于固定点数的指导方针。 12-30 点的任何解决方案都可以。 点会保持固定大小吗?如果 dot 是已知大小,则可能在新行的每个中断处使用媒体查询。 @AndrewClody 是的,它们将保持相同的大小。实际上,您是对的,以这种方式实现它并不难,每行可能有 3 个点 - 三个不同的媒体查询应该没问题,然后将边距添加到特定的点元素。但是有没有更优雅的方式来处理每行十几个点? 如果这对某些事情很重要,那么创建这个具有重复背景和css-gradients 的模式是小菜一碟。仍在思考是否有一种好方法可以动态地处理元素并为其设置样式,但这似乎是一个真正的挑战。 【参考方案1】:

仅使用 CSS 而无需媒体查询偏移每个奇数行的一种方法是使用 shape-outside 属性。 请注意,此属性为candidate recomendation,因此具有low browser support。

这是一个最多支持 5 行的示例:

.wrapper 
  width: 100%;

.wrapper div 
  width: 50px;
  height: 50px;
  margin: 50px;
  border-radius: 50%;
  display: inline-block;
  background-color: #000;
  text-align: center;

.wrapper:before 
  content: '';
  float: left;
  width: 75px;
  height: 9999px;
  -webkit-shape-outside: polygon(0px 150px, 75px 150px, 75px 300px, 0 300px, 0px 450px, 75px 450px, 75px 600px, 0px 600px);
  shape-outside: polygon(0px 150px, 75px 150px, 75px 300px, 0 300px, 0px 450px, 75px 450px, 75px 600px, 0px 600px);
<div class="wrapper">
  <div></div><div></div><div></div><div></div><div></div>
  <div></div><div></div><div></div><div></div><div></div>
  <div></div><div></div><div></div><div></div><div></div>
  <div></div><div></div><div></div><div></div><div></div>
</div>

【讨论】:

poligon 函数如何与shape-outside 结合使用?看起来像是硬编码的东西,还尝试在您的代码中添加更多元素,但没有奏效,在我看来它不灵活。 @Tarekis 多边形是手工编码的,需要为可能的最大行数制作。在我的示例中,只有 5 行可能。 以为是这样,老实说,我无法真正解码 polygon 所做的事情。对我来说似乎是一个不完美的答案,不确定它是否甚至可以只做这个 CSS,也想不出一个完美的答案。 PS:看到你的codepen,好东西! ;) @Tarekis 谢谢。你是对的,这不是一个完美的解决方案,尤其是考虑到浏览器支持。 浏览器支持仍然非常微妙,只有当前版本的 Chrome、Safari 和 Opera 启用了 shape-outside 属性,但这仍然是解决所描述问题的最合适的解决方案。【参考方案2】:

这是您可以查看的另一种方法:

HTML

<div class="wrapper">
  <div class="float-right"></div>
  <div class="float-left"></div>
  <div class="float-right"></div>
  <div class="dot">Element 1</div>
  <div class="dot">Element 2</div>
  <div class="dot">Element 3</div>
  <div class="dot">Element 4</div>
  <div class="dot">Element 5</div>
  <div class="dot">Element 6</div>
  <div class="dot">Element 7</div>
  <div class="dot">Element 8</div>
  <div class="dot">Element 9</div>
  <div class="dot">Element 10</div>
  <div class="dot">Element 11</div>
  <div class="dot">Element 12</div>
</div>

CSS

wrapper 
  width: 100%;

.dot 
  width: 150px;
  height: 150px;
  margin: 15px;
  border-radius: 50%;
  display: inline-block;
  background-color: #999;


.float-left, .float-right 
  border: doted blue 1px; /* temporary */
  width: 100px;
  height: 180px;

.float-left 
  float: left;
  clear: right;

.float-right 
  float: right;
  clear: left;

您无需尝试在某些元素上设置边距,而是在页面中创建浮动“障碍物”以将点向左或向右移动。

您可以根据需要显示任意数量的浮动 div,但问题是当使用较小的屏幕分辨率时,当它们在页面底部变得“无点”时,您必须隐藏它们。我认为您可以通过媒体查询或引导类来管理它,根据屏幕分辨率调节浮动 div 的数量。

【讨论】:

【参考方案3】:

好吧,这让我思考了一下,但我认为我得到了一些相当可接受的东西,它适用于各种环境、页面大小和任意数量的点。

它虽然有一个限制!您必须固定每行的点数。

让我们看看,我选择在一整行上使用 9 个点,这使得计算变得非常容易,因为你必须将你的宽度分成你选择的任意数量的点 + 1,因为总是有半个点的宽度空间在左侧或右侧。

HTML:

您将重复这些代码块:

  <div class="container">
      <div class="dummy"></div>
      <div class="element">
      </div>
  </div>

通过Nathan Ryan 的really smart trick,您现在可以选择任意宽度的元素,并且它们的高度会适应。

CSS:

现在进行一些计算(您可以使用 less 或 sass 来动态计算并更改每行的点数)。我将在代码中注释以了解这些属性的作用。

.container 
    display: inline-block;
    position: relative;
    /* As i want to calculate for 10 dots i have to make a dot + margin take up
    exactly 10% of the document's width, here i chose a 3/4 ratio per dot*/
    width: 7.5%;    
    margin-right: 2.5%;



/* Here you have to choose every (rowLength)*2 and add 1 or (rowLength) + 1, 
depending which line you want your offset to start */
.wrapper .container:nth-child(18n+10)   
    /* And finally align it half of a dot's complete size*/
    margin-left: 5%;

.dummy 
    margin-top: 100%;

.element 
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    border-radius: 50%;
    display: inline-block;
    background-color: #f1ea75;

你可以check it out here。

..是的,我知道,熊太棒了! (ง⚆ᴥ⚆)ง

【讨论】:

对不起,我不明白这是如何回答这个问题的。 OP 明确指定点的宽度/高度应该是固定的,并且已经在使用 nth-child() 选择器来偏移示例中的偶数行。这就是说,您使用的方法很棒并且允许awesome layouts(结合媒体查询) 如果这是真的,我一定是误读/理解了这个问题,真可惜。我解释说她想要响应宽度的点,现在不打算采用另一种方法。 :/ 不过,熊万岁? @web-tiki 正是我想听到的!哈哈:D @Tarekis - 是的,我想要固定宽度的点,虽然我发现你的方法也很有创意,并且相信它会帮助其他人搜索这个或类似的问题 @jessica 谢谢你,感谢你的友好评论。我很快就明白我的答案不是一个适用的解决方案,真可惜,希望它可以在任何时候帮助任何人! (ง⚆ᴥ⚆)ง

以上是关于在响应式布局中每隔 n 行偏移一次的主要内容,如果未能解决你的问题,请参考以下文章

响应式布局设计

到底什么是响应式布局

如何使用响应大小的图像防止卡顿并减少布局偏移?

响应式布局

H5响应式布局 响应式图片 响应式布局网站怎么写?

8.10 响应式布局2 弹性网络 (栅格系统) 响应式图片