html - 使元素均匀地填充给定空间

标签 html css flexbox css-grid

我希望 div 元素的布局如下所示:

如果屏幕足够大,那么单行中有很多 block 。

例如,我想将每个 block 的最小宽度设置为 250px。

因此,在大屏幕上,我可以为此类元素添加以下内容。右边是 map (可关闭),如果用户隐藏它,那么一行中将有 6 个 block 。

large screen

接下来,当我水平缩小浏览器窗口时,所有 block 都不适合该行,因此它们会移动到下一行。好的,现在的工作方式是他们执行第二行,但他们在 div block 和 map 之间留有空间。就像下图一样。

ramaining space between divs and map sidebar

我想要这样的布局,如果 4 个 block 不适合空间,那么可以有 3 个 block ,但它们同样填充剩余空间(没有剩余的黄色空间)。请参阅下面的图片。

3 blocks of divs per row

然后当浏览器窗口缩小更多时,它应该如下所示

2 blocks of divs per row

在移动设备和非常窄的浏览器窗口上:

1 block of div per row

好吧,我可以使用这样的 CSS 样式实现类似的效果:

#parent {
    display: flex;
    flex-wrap: wrap;
}

.child {
    width: calc(33% - 15px);
    margin-left: 10px;
    margin-top: 10px;
    margin-bottom: 20px;  
    min-width: 250px;
}

那么我应该使用媒体查询手动更改它:

calc(25% - 15px) //lg
calc(33% - 15px) //md
calc(50% - 15px) //sm
calc(100% - 15px) //xs 

本地图消失时甚至可能是这样

calc(16.667% - 15px) //lg+no map

好吧,FLEX 不太向后兼容,所以我可以玩更多,做这样的事情:

#parent {

}

.child {
    width: calc(33% - 15px);
    margin-left: 10px;
    margin-top: 10px;
    margin-bottom: 20px;  
    min-width: 250px;
    float: left; 
}

然后还根据屏幕尺寸手动更改此宽度 并使用

在最后一个元素后添加 clear: left
.block-offer:nth-last-child(1):after { 
    clear: left; 
}

或者在其他元素进行其他clearfix之前

甚至(有必要吗?)在每行后面添加clear: left,使用:

.block-offer:nth-child(4n+1) { 
   clear:left; 
}
.block-offer:nth-child(3n+1) { 
   clear:left; 
}
.block-offer:nth-child(2n+1) { 
   clear:left; 
}
.block-offer:nth-child(1n+1) { 
   clear:left; 
}

像这样的宽度: calc() 取决于屏幕尺寸和 divs witdh

但是我需要使用许多媒体查询,我想将这个 CSS 包装在一些 Angular 2+ 组件中,并且只有这样的东西:

<blocks-container max-cols="6"> 
    <block min-width="250px"></block> 
    <block min-width="250px"></block>
     ...
</blocks-container>

我认为使用 @media 查询会稍微改善这种行为,但我的组件将与屏幕尺寸紧密结合,并且我认为没有像我希望的那样通用来灵活地指定 max-cols 和 min-宽度。

最佳答案

这是一种可能的解决方案,它结合了 CSS flexbox 和网格:

body {
  display: flex;                 /* 1 */
}
article {                        /* 2 */
  flex: 1;                       /* 2 */                   
  margin-right: 10px;
  display: grid;                 /* 3 */
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));  /* 4 */
  grid-auto-rows: 100px;         /* 5 */
  grid-gap: 10px;                /* 6 */
}
map {
  min-height: 200px;            /* 7 */
  width: 250px;
  background-color: orangered;
}
@media (max-width: 800px) {     /* 8 */
  map { display: none; }
}
section {                       
  background-color: lightblue;
  border: 2px solid gray;
}
<article>
  <section></section>
  <section></section>
  <section></section>
  <section></section>
  <section></section>
  <section></section>
</article>
<map></map>

jsFiddle

注释:

  1. 创建一个包含两个 Flex 元素的 Flex 容器。
  2. 第一项 (article) 包含包装 block (section)。它设置为 flex: 1 以消耗所有可用宽度。
  3. 第一项被制作成网格容器,因此网格属性可以是 应用于 block 。
  4. 见下文。
  5. grid-auto-rows属性设置自动生成的行的高度。
  6. grid-gap property 是 grid-column-gap 和 grid-row-gap 的简写。此规则设置了网格元素之间的 10px 间隙。
  7. 第二个 Flex 元素是 map (map),由于其同级元素上的 flex: 1 而使其右对齐。
  8. 媒体查询会删除 map ,以模拟用户行为。

auto-fill函数允许网格排列尽可能多的网格轨道(列或行),而不会溢出容器。这可以创建与 Flex 布局的 flex-wrap:wrap 类似的行为。

minmax()函数设置网格轨道的最小和最大尺寸范围。在上面的代码中,列轨道的宽度最小为 250px,最大为可用空间 (1fr)。这可以防止显示空白区域。

fr单位表示可用空间的一小部分。它类似于Flex布局中的flex-grow

浏览器对 CSS 网格的支持

  • Chrome - 自 2017 年 3 月 8 日起全面支持(版本 57)
  • Firefox - 自 2017 年 3 月 6 日起全面支持(版本 52)
  • Safari - 自 2017 年 3 月 26 日起全面支持(版本 10.1)
  • Edge - 自 2017 年 10 月 16 日起提供全面支持(版本 16)
  • IE11 - 不支持当前规范;支持过时版本

完整图片如下:http://caniuse.com/#search=grid

关于html - 使元素均匀地填充给定空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43833215/

相关文章:

javascript - 如何在本地存储AngularJS中存储按钮值?

html - 对齐附加表格旁边的文本

html - 展开的 flex 盒元素之间的垂直边界

html - float :right is limited by its parent div, 使其右对齐/向下对齐

html - 错误使用背景图片 :url

html - 列表类型样式 : none does not remove bullet points

尊重嵌入内容(iframe、对象、嵌入)宽度属性的 CSS 宽度值

javascript - 问题更新 css 转换的 div 的高度(FlexBox,Sass)

css - Flexbox 新手——我需要做什么?

html - 我可以在 Markdown 中创建带有 'target="_blank"' 的链接吗?