代码之家  ›  专栏  ›  技术社区  ›  Brett DeWoody

具有最大宽度、居中内容的CSS网格布局

  •  0
  • Brett DeWoody  · 技术社区  · 5 年前

    我正在学习CSS网格(我知道,早该学了)。我曾经挑战过自己,把一个相对标准的基于浮动的布局转换成网格,但是最后一部分我还是搞不懂。

    我的目标是在内容(logo+nav,sidebar+content)居中的布局中使用 max-width . 例如,logo+nav应该有一个 最大宽度 600像素。有一个完整的高度要求的视窗/一个完全覆盖高度的标志。

    第一列(logo和sidebar)应该缩小以适合它们的内容,因此第一列的宽度与logo/sidebar之间的宽度相同。导航/内容应填充 最大宽度

    以下是我最好的尝试。主内容的宽度不填充 最大宽度 . 相反,主要内容的宽度是Logo的宽度+250px(由网格列定义的宽度)。

    最大宽度

    body {
      margin: 40px;
    }
    
    .fill {
      grid-column-start: 1;
      grid-column-end: 6;
      grid-row-start: 1;
      grid-row-end: 1;
      background-color: gray;
    }
    
    .logo {
      grid-area: logo;
      font-size: calc(1rem + 4vw);
    }
    
    .sidebar {
      grid-area: sidebar;
    }
    
    .content {
      grid-area: content;
    }
    
    .nav {
      grid-area: nav;
      text-align: right;
    }
    
    .footer {
      grid-area: footer;
    }
    
    .wrapper {
      display: grid;
      grid-gap: 10px;
      grid-template-columns: auto min-content 120px 120px auto;
      grid-template-areas: "... logo nav nav ..." "... sidebar content content ..." "... footer  footer  footer ...";
      background-color: #fff;
      color: #444;
    }
    
    .box {
      background-color: #444;
      color: #fff;
      border-radius: 5px;
      padding: 10px;
    }
    
    .header,
    .footer {
      background-color: #999;
    }
    <div class="wrapper">
      <div class="fill"></div>
      <div class="box logo">Logo</div>
      <div class="box nav">Nav</div>
      <div class="box sidebar">Sidebar</div>
      <div class="box content">Content
        <br /> More content than we had before so this column is now quite tall.</div>
      <div class="box footer">Footer</div>
    </div>

    CSS网格是否可以实现,如果可以,如何实现?

    1 回复  |  直到 5 年前
        1
  •  3
  •   kukkuz    5 年前

    你可以有两列 网格 具有 grid-template-columns: auto 1fr 所以 第一列 获取其内容的宽度( 与徽标/侧边栏之间的宽度一样宽 )以及 第二列 占用剩余空间(注意,我已经设置了 max-width: 600px ).

    我也有一个要求有一个坚实的填充背景覆盖 高度标识/导航行)

    为此,您可以执行以下操作:

    1. 修理 logo nav 通过设置 grid-row grid-column 属性

    2. 现在使用 伪元素 wrapper 重叠第一行(但是 堆叠的 低于使用 z-index

    3. 设置 margin-left 属性as calc(-50vw + 50%) width 作为100vw来拉伸 实心填充背景 穿过视口。

    body {
      margin: 40px;
    }
    
    .wrapper {
      display: grid;
      grid-gap: 10px;
      grid-template-columns: auto 1fr; /* 2-column grid */
      /* background-color: #fff;*/
      color: #444;
      max-width: 600px; /* max-width of the layout */
      margin: 0 auto; /* center in the viewport */
    }
    .logo {
      font-size: calc(1rem + 4vw);
      grid-row: 1; /* fix the logo in the first row */
      grid-column: 1; /* fix the logo in the first column */
    }
    .nav {
      text-align: right;
      grid-row: 1;  /* fix the nav in the first row */
      grid-column: 2;  /* fix the nav in the second column */
    }
    
    .footer {
      grid-column: span 2; /* footer spans the two columns */
    }
    
    .box {
      background-color: #444;
      color: #fff;
      border-radius: 5px;
      padding: 10px;
    }
    
    .header,
    .footer {
      background-color: #999;
    }
    
    .wrapper:after { /* position this in the first row */
      content: '';
      display: block;
      grid-row: 1;
      grid-column: 1/ 3;
      width: 100vw;
      margin-left: calc(-50vw + 50%);
      background: gray;
      z-index: -1; /* push it behind the first row */
    }
    <div class="wrapper">
      <div class="box logo">Logo</div>
      <div class="box nav">Nav</div>
      <div class="box sidebar">Sidebar</div>
      <div class="box content">Content
        <br /> More content than we had before so this column is now quite tall.</div>
      <div class="box footer">Footer</div>
    </div>
        2
  •  0
  •   Michael Benjamin    5 年前

    居中

    水平居中网格容器相对简单。在父对象上使用弹性对齐特性:

    body {
      display: flex;
      justify-content: center;
    }
    

    最大宽度

    max-width flex 财产。

    .wrapper {
      flex: 600px 0 1;
    }
    

    这条规则说:

    • flex-basis: 600px 起始宽度(mm)
    • flex-grow: 0 (项目不能扩展到超过600px)
    • flex-shrink: 1 (物品会缩水)

    max-width: 600px .


    2列布局

    你写道:

    第一列(logo和sidebar)应该缩小以适合它们的内容,因此第一列的宽度与logo/sidebar之间的宽度相同。导航/内容应该填充最大宽度所允许的剩余空间。

    试试这个:

    .wrapper {
      flex: 600px 0 1;
      display: grid;
      grid-template-columns: min-content 1fr;
    }
    

    body {
      margin: 40px;
      display: flex;
      justify-content: center;
    }
    
    .wrapper {
      flex: 600px 0 1;
      display: grid;
      grid-gap: 10px;
      grid-template-columns: min-content 1fr;
      grid-template-areas: "logo  nav" 
                           "sidebar content" 
                           "footer footer";
      background-color: #fff;
      color: #444;
    }
    
    .logo {
      grid-area: logo;
      font-size: calc(1rem + 4vw);
    }
    
    .sidebar {
      grid-area: sidebar;
    }
    
    .content {
      grid-area: content;
    }
    
    .nav {
      grid-area: nav;
      text-align: right;
    }
    
    .footer {
      grid-area: footer;
    }
    
    .fill {
      background-color: gray;
    }
    
    
    .box {
      background-color: #444;
      color: #fff;
      border-radius: 5px;
      padding: 10px;
    }
    
    .header,
    .footer {
      background-color: #999;
    }
    <div class="wrapper">
      <div class="box logo">Logo</div>
      <div class="box nav">Nav</div>
      <div class="box sidebar">Sidebar</div>
      <div class="box content">Content
      <br /> These lines wrap when the text hits 600px maximum width. These lines wrap when the text hits 600px maximum width. These lines wrap when the text hits 600px maximum width. These lines wrap when the text hits 600px maximum width. These lines wrap when the text hits 600px maximum width. These lines wrap when the text hits 600px maximum width.</div>
      <div class="box footer">Footer</div>
    </div>