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

时间:2018-09-26 19:13:08

标签: 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>

就像标题指出的那样,“我不想使用js”。

2 个答案:

答案 0 :(得分:1)

在媒体屏幕中,您可以设置2行来完成这项工作 我也建议在网格布局中使用“ fr”代替像素。

您可以在https://css-tricks.com/snippets/css/complete-guide-grid/

上找到不错的指南

.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;
        grid-template-rows: 40px;
        justify-content: center;
        grid-auto-flow: rows;
      }
      .side-menu:nth-child(odd) {
      width: 100%;
      height: 50px;
      background-color: red;
        grid-column: 1;
      }

      .side-menu:nth-child(even) {
      width: 100%;
      height: 50px;
      background-color: red;
        grid-column: 3;
      }
    }

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

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


    .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>

答案 1 :(得分:0)

您尚未在网格中定义任何行:

.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