html - CSS网格布局,简单的响应式设计

标签 html css grid grid-layout css-grid

我正在尝试理解 CSS 网格。我的布局包含两个菜单(红色),中间一个主内容框(蓝色)的每一侧都有一个。

当屏幕变小并且没有足够的空间容纳 3 列时,我希望第二个(右侧)侧边菜单出现在第一个(左侧)侧边菜单的正下方。

enter image description here

将主要内容和侧边菜单的高度视为随机值,因为高度会根据其中内容/菜单项的数量而变化。无论高度如何,解决方案都应该有效。

我当前的布局几乎可以正常工作,除了第二个菜单出现在主要内容末尾的下方,而不是紧跟在第一个菜单之后。我该如何解决这个问题?

.main-container {
  width: 100%;
  height: 100%;
}

@media only screen and (min-width: 400px) {
  .main-container {
    display: grid;
    grid-gap: 20px;
    grid-template-columns: 40px 80px 40px;
    justify-content: center;
  }
}

@media only screen and (max-width: 400px) {
  .main-container {
    display: grid;
    grid-gap: 20px;
    grid-template-columns: 40px 80px;
    justify-content: center;
  }
}

.side-menu {
  width: 100%;
  height: 50px;
  background-color: red;
}

.main-content {
  width: 100%;
  height: 300px;
  background-color: blue;
}
<div class="main-container">
  <div class="side-menu"></div>
  <div class="main-content"></div>
  <div class="side-menu"></div>
</div>

如标题所述“CSS 网格布局”我不想使用 js。

最佳答案

您还没有在网格中定义任何行:

.main-container {
  display: grid;
  grid-gap: 20px;
  grid-template-columns: 40px 80px 40px;
  justify-content: center;
}

因此,所有行都是 implicit ,这意味着它们是自动创建的以容纳元素。

隐式行的大小函数是 grid-auto-rows其默认值为 auto。这意味着行占用内容的大小。

您已经设置了网格元素的大小:

.side-menu {
  height: 50px;
}

.main-content {
  height: 300px;
}

因此 .main-content,作为网格元素中较高的一个,设置了行的高度:

enter image description here

如您所见,您有一个只有一行的网格容器。

然后您的媒体查询会针对较小的屏幕启动:

@media ( max-width: 400px ) {
  .main-container {
    grid-template-columns: 40px 80px;
  }
}

新的 grid-template-columns 规则将网格从三列更改为两列。

这会强制网格创建第二个隐式行以容纳第二个 .side-menu,其列已被删除。

enter image description here

简而言之,第二行存在于第一行之下。第一行是 300px 高。这会导致第一个菜单和第二个菜单之间存在较大的垂直间隙。


一种可能的解决方案

使用多个较小的行并使您的元素跨越它们。

下面的代码呈现如下:

enter image description here

.main-container {
    display: grid;
    grid-template-columns: 40px 80px 40px;
    grid-auto-rows: 10px;  /* new */
    grid-column-gap: 20px; /* adjusted */
}

.side-menu:first-child {
  /* height: 50px; */
  grid-column: 1;
  grid-row: span 5;
}

.side-menu:last-child {
  /* height: 50px; */
  grid-column: 3;
  grid-row: span 5;
}

.main-content {
  /* height: 300px; */
  grid-column: 2;
  grid-row: span 30;
}

@media ( max-width: 400px ) {
  .main-container {
    grid-template-columns: 40px 80px;
  }
  .side-menu:last-child {
    grid-column: 1;
    grid-row: 7 / span 5;
  } 
}

.main-content { background-color: blue; }
.side-menu    { background-color: red;  }
<div class="main-container">
  <div class="side-menu"></div>
  <div class="main-content"></div>
  <div class="side-menu"></div>
</div>

codepen demo

关于html - CSS网格布局,简单的响应式设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52524632/

相关文章:

html - 下拉菜单宽度更改为动态

javascript - JQuery动态改变html内容

html - 冗长的子菜单列表项破坏了 CSS 导航菜单的功能

grid - 如何在给定行和列索引的情况下获取 Dojo 网格单元格的实际 DOM 节点?

html - 带有 JSF 传递的单选按钮?

css - h2 标题在移动 Safari 上有不同的颜色

javascript - 获取子元素的父 DOM 元素

excel - ComponentArt:导出网格数据

wpf - 具有自动高度的网格行中的列表框。滚动条不工作

javascript - 隐藏/显示多个 div