【问题标题】:CSS - Responsive grid with equal margins and fixed size blocksCSS - 具有相等边距和固定大小块的响应式网格
【发布时间】:2014-07-10 15:00:14
【问题描述】:

我正在尝试突破 CSS 的限制,以复制打印中常见的网格布局。

要求:

  1. 块之间以及块与容器边缘之间的边距必须相等。
  2. 布局必须是响应式的,每行的块数必须适应窗口的大小。
  3. 最后一行必须左对齐
  4. 块的宽度/高度是固定的
  5. 不使用空的非语义 HTML 元素
  6. 纯CSS解决方案,无JS

所以,我有如下标记:

<ul>
    <li>
       <img src="thumbnail.jpg">
       <span>Introduction and Curriculum</span>
    </li>
    <li>
       <img src="thumbnail.jpg">
       <span>Equipment and Workspace Prep</span>
    </li>
    ...
</ul>

这是我要实现的目标的模型。

【问题讨论】:

  • 这是您想要实现的布局吗? jsfiddle.net/webtiki/KrA6M
  • 某种?这是我想要的交互式版本。 codepen.io/norbauer/pen/bLCpa 不幸的是,它使用了需要插入空的 &lt;li&gt; 元素的 hack,我需要避免这种情况。我正在考虑通过 JS 插入它们,但我首先想知道我所提议的是否可以通过更传统的 CSS 实现。 JSFiddle 中提出的代码更加迟钝。 :) (尽管它至少具有不使用 DOM 的优势。)
  • 您是否已经尝试过使用浮动和nth-child 进行清算+保证金修正?这些可以在不同的断点处更改。
  • 浮动和修复是我想要避免的事情(我认为浮动仅适用于文本块内的浮动图像,而不是更大规模的布局。)我也许应该澄清一下我的观点问题是看看 CSS 中是否有适当的优雅方法。我不关心只是完成它,因为我知道一些简单的技巧(例如添加具有特定宽度的虚拟空列表项并使用 flexbox。)我只是想在这里学习 CSS 最佳实践。
  • 您还可以查看以下 2 个答案以了解具有严格要求的网格:stackoverflow.com/a/23803215/1811992stackoverflow.com/a/20457076/1811992

标签: html responsive-design grid-layout css


【解决方案1】:

您可以使用 CSS calc() function。虽然它不会阻止使用媒体查询,但它可以计算元素和容器之间的边距

DEMO

此演示使用:

  1. calc() CSS 函数。在这种情况下,它将被 IE9+ 支持。您可能希望为某些 webkit 浏览器添加 -webkit- 前缀。如需更多信息,请参阅canIuse
  2. 4 个媒体查询来更改一行中显示的元素数量和相应的边距。
  3. inline-block 元素。这涉及处理空白(在演示中我使用了字体大小技术,但您可以使用另一种技术,see here)。

解释:

媒体查询断点:

它们是根据元素的宽度计算的。由于每个元素都是 200px 宽,我应该在 screen width = 400px/600px/800px/1000px 处选择断点,但由于媒体查询包括滚动条,使用这些值,元素将没有足够的空间并相互重叠。

滚动条在每个浏览器上的宽度都不相同,因此我选择了更高的值以确保不会发生重叠。

这是带有“逻辑”媒体查询断点的这种行为的example

保证金计算:

首先,百分比边距和内边距始终根据容器的剩余宽度 (exception) 计算,因此顶部和底部边距/内边距与左/右边距/内边距的计算相同。

基本上,边距大小的计算是:

(remaining width (=100%) - the sum of grid elements width) / number of gaps 

但是

左侧和顶部间隙是容器的填充,其他间隙是块元素的右侧和底部边缘。块的保证金计算必须考虑到这一点,划分是由number of gaps -1


HTML:

<ul id="container">
    <li class="block">...</li>
    <li class="block">...</li>
    ...
</div>

CSS:

#container{
    font-size:0;    
    padding-top: calc((100% - 1000px)/6);
    padding-left:calc((100% - 1000px)/6);}

.block {
    font-size:20px;
    width: 200px;
    height: 200px;
    display:inline-block;
    margin-right: calc((100% - 1000px)/5);
    margin-bottom: calc((100% - 1000px)/5);
}

@media screen and (max-width: 430px) {
    .block {
        margin: calc(50% - 100px);
    }
}

@media screen and (min-width: 431px) and (max-width: 630px) {
    #container{
        padding-top: calc((100% - 400px)/3);
        padding-left:calc((100% - 400px)/3);
    }
    .block {
        margin-right: calc((100% - 400px)/2);
        margin-bottom: calc((100% - 400px)/2);
    }
}
@media screen and (min-width: 631px) and (max-width: 830px) {
    #container{
        padding-top: calc((100% - 600px)/4);
        padding-left:calc((100% - 600px)/4);
    }
    .block {
        margin-right: calc((100% - 600px)/3);
        margin-bottom: calc((100% - 600px)/3);
    }
}
@media screen and (min-width: 831px) and (max-width: 1030px) {
    #container{
        padding-top: calc((100% - 800px)/5);
        padding-left:calc((100% - 800px)/5);
    }
    .block {
        margin-right: calc((100% - 800px)/4);
        margin-bottom: calc((100% - 800px)/4);
    }
}

【讨论】:

  • 我可能会对此进行一些调整以供我最终使用,但这是一个非常有创意的解决方案,并且非常受欢迎。它是纯 CSS 并且不涉及任何(至少对我而言)感觉像骇客的东西。干得好。
  • 顺便说一句,如果你能解释你的数字来自哪里,以及你为什么选择你所做的媒体查询断点,这可能会有所帮助。再次感谢。
  • @RyanNorbauer 您将不得不根据元素和容器的大小调整此解决方案。我将编辑我的问题以包含更多解释。您是否介意我也大幅编辑您的问题以使其更通用且更容易为其他用户找到?
  • 无论如何。 :) 问这个问题的目的是让我和其他人可以更好地学习 CSS,而不仅仅是为了解决当前的特定问题。
【解决方案2】:

Nth-child 和在各自断点处实现可能是最佳实践方法和最轻量级的解决方案。

还有一些其他选项,例如 1. 使用 jQuery 测量屏幕宽度并在不同的断点处分配样式 2. 使用负边距为容器分配一个类,这样你就不需要接触实际的边距

...等等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-09
    • 2017-05-20
    • 2012-08-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多