如何使用CSS Grid布局粘贴页脚?

时间:2017-09-11 15:05:18

标签: html css html5 css3 css-grid

我在CSS网格布局中找到了粘性页脚的this CodePen solution,但它对我来说有两个问题:

  1. min-height: 100%height: 100%
  2. 有点难看
  3. 它仅适用于正文中的两个元素(div和footer)
  4. 我需要适合这种HTML结构的东西:

    <body>
        <nav>Some navigation buttons</nav>
        <main>The content</main>
        <footer>Copyrights and stuff</footer>
    </body>
    

    我真的不想将<nav><main>打包成<div>,我很乐意在纯CSS中执行此操作。

    // Not required!
    // This is just to demo functionality.
    
    $("#add").on("click", function() {
      $("<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>").appendTo(".content");
    });
    html {
      height: 100%;
    }
    
    body {
      min-height: 100%;
      display: grid;
      grid-template-rows: 1fr auto;
    }
    
    .content {
      padding: 20px;
    }
    
    .footer {
      grid-row-start: 2;
      grid-row-end: 3;
    }
    
    * {
      box-sizing: border-box;
    }
    
    body {
      margin: 0;
      font: 16px Sans-Serif;
    }
    
    h1 {
      margin: 0 0 20px 0;
    }
    
    p {
      margin: 0 0 20px 0;
    }
    
    .footer {
      background: #42A5F5;
      color: white;
      padding: 20px;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div class="content">
      <h1>Sticky Footer with Grid</h1>
      <p><button id="add">Add Content</button></p>
    </div>
    
    <footer class="footer">
      Footer
    </footer>

5 个答案:

答案 0 :(得分:13)

这是一个CSS网格解决方案,但使用目标类更好 使用网格区域将非常简单:

html,body{
  height: 100%;
}
body{
  margin: 0;
}
body {
  display: grid;
  grid-gap: 10px;
  height: 100%;
  grid-template-columns:1fr;
  grid-template-areas:
            "nav"
            "main"
            "footer";
  grid-template-rows: 100px 1fr 80px;
}
nav {
  grid-area: nav;
}

main {
  grid-area: main;
}

footer {
  grid-area: footer;
}
nav {
  background-color: #7E57C2;
}
main {
  background-color: #F8BBD0;
}
footer {
  background-color: #7E57C2;
}

https://codepen.io/whisher/pen/vWmvQw

答案 1 :(得分:4)

使用单行CSS实现粘性页脚,即:min-height: 100vh

以下示例:

body {
    width: 100%;
    height: 100%;
    margin: 0;
    display: grid;
    grid-template-columns: [column-line-1] minmax(128px, 256px) [column-line-2] auto [column-line-3] minmax(128px, 256px) [column-line-4];
    grid-template-rows: [row-line-1] 48px [row-line-2] auto [row-line-3] auto [row-line-4] auto [row-line-5] auto [row-line-6];
    background:#fafafa;
    /*Below provides sticky footer*/
    min-height: 100vh;
}

body > aside {
    background:#9e9e9e;
}

body > aside > section {
    margin: 0px 12px 0px 12px;
}

body > header {
    display: flex;
    flex-flow: row wrap;
    justify-content: center;
    align-content: center;
    align-items: flex-start;
}

body > header > section {
    flex: 1 1 auto;
    align-self: center;
    min-width: 100%;
    min-height:48px;    
}

body > header > nav {
    flex: 0 1 auto;
    align-self: auto;
    min-width: 100%;
    min-height:48px;
    
    display: flex;
    flex-flow: row nowrap;
    align-content: center;
    align-items: center;
    
    margin-left:12px;
    margin-right:12px;
}

body > header > nav > section {
    flex: 1 1 auto;
    align-self: center;
    
    display: flex;
    flex-flow: row nowrap;    
    align-content: center;
    align-items: center;
    
    height:auto;
    width:50%;
}

body > header > nav > section:nth-of-type(1) {
    justify-content: flex-start;
}

body > header > nav > section:nth-of-type(2) {
    justify-content: flex-end;
}

body > header > nav > section > div {
    flex: 0 1 auto;
    align-self:center;
    
    display: flex;
    flex-flow: row nowrap;    
    align-content: center;
    align-items: center;  
    justify-content: center;
    
    margin: 0px 12px 0px 12px;
}

body > main {
    background:#e3f2fd;
    
}

body > main > section {
    margin: 0px 12px 0px 12px;
}

body > nav {
    
    background:#e0e0e0;
}
body > nav > section {
    display: grid;
    margin: 0px 12px 0px 12px;
}

body > footer {
    grid-column-start: column-line-1;
    grid-column-end: column-line-4;
    grid-row: row-line-5;
    background:#eeeeee;

}

body > footer > section {
    margin: 0px 12px 0px 12px;
}


@media screen and (max-width: 479px) {
    header {
        grid-column-start: column-line-1;
        grid-column-end: column-line-4;
    }
    main {
        grid-column-start: column-line-1;
        grid-column-end: column-line-4;
        grid-row: row-line-2;
    }
    aside {
        grid-column-start: column-line-1;
        grid-column-end: column-line-4;
        grid-row: row-line-3;
    }
    nav {
        grid-column-start: column-line-1;
        grid-column-end: column-line-4;
        grid-row: row-line-4;
    }
}

@media screen and (min-width: 480px) and (max-width: 639px) {
    nav {
        grid-column: column-line-1;
        grid-row: row-line-2;
    }
    aside {
        grid-column: column-line-1;
        grid-row-start: row-line-3;
        grid-row-end: row-line-5;
    }
    main {
        grid-column: column-line-2 / column-line-4;
        grid-row-start: row-line-1;
        grid-row-end: row-line-5;
    }
}

@media screen and (min-width: 640px) {
    header {
        grid-column-start: column-line-1;
        grid-column-end: column-line-4;
    }
    nav {
        grid-column: column-line-1;
        grid-row-start: row-line-2;
        grid-row-end: row-line-5;
    }
    aside {
        grid-column: column-line-3;
        grid-row-start: row-line-2;
        grid-row-end: row-line-5;
    }
    main {
        grid-column: column-line-2;
        grid-row-start: row-line-2;
        grid-row-end: row-line-5;
    }
}
<!DOCTYPE html>
<html lang="en">
<!-- 
    Created by Ron Royston, https://rack.pub, © 2018 MIT License
    Available online at https://github.com/rhroyston/html5
        
        ⚠ NO COMMENTS ABOVE DOCTYPE declaration.
        
        ⚠ Consider page viewing experience across device types, sometimes called Responsive Web Design, RWD.
        
        ⚐ Mozilla Developer Network HTML ELEMENT REFERENCE
            https://developer.mozilla.org/en-US/docs/Web/HTML/Element
            
        ⚐ Validate HTML with The W3C Markup Validation Service
            https://validator.w3.org/
            
        ⚐ Favicon image displays in browser tab
            http://realfavicongenerator.net/
-->

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <!-- Mobile viewing enhancement -->
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- ⚠ Description should be roughly 155 characters, no double quotes, use keywords -->
    <meta name="description" content="CSS Responsive Grid Layout. Simple. Clean. Golden." />
    <!-- ⚠ Format as Primary Keyword - Secondary Keyword | Brand Name, keep under 55 characters -->
    <title>Golden Grid - CSS Responsive Grid Layout. Simple. Clean. Golden.</title>
    
</head>
<body class="mdc-typography">
    <header>
        <nav>
            <section>
                <div>
                    <img src="//intrest.run/media/character.png" height="24px">
                </div>
            </section>
            <section>
                <div>
                    <button>
                        Sign In
                    </button>
                </div>
            </section>
        </nav>
    </header>
    <main>
        <section>
            <h4>Page Name</h4>
        </section>      
        
        <section>
            <p>2 Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>    
        </section>
        
        <section>
            <p>3 Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>    
        </section>

    </main>
    <nav>
        <section>
            <!--
                This area is normally on the left hand side of page
            -->
            <h3>Navigation</h3>
            <a href="#">Home</a>
            <a href="#">Chapter 1</a>
            <a href="#">Chapter 2</a>
            <a href="#">Chapter 3</a>
            <a href="#">Chapter 4</a>
        </section>
    </nav>
    <aside>
        <!--
            This area is normally on the right hand side of page
        -->
        <section>
            <h3>Sidebar</h3>
            <p>Aside Element. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
        </section>
    </aside>
    <footer>
        <section>
            <h3>Footer</h3>
            <p>Footer Element. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
        </section>
    </footer>
</body>

</html>

答案 2 :(得分:3)

CSS Grid是一个很好的工具,可以将复杂的布局组合在一起。

但是你正在寻找一个简单的单列网格,有三行,页脚固定在容器的底部。

我建议在这种情况下,flexbox是一种更简单,更有效的解决方案。 (您始终可以在每个弹性项目中使用网格。)

// Not required!
// This is just to demo functionality.

$("#add").on("click", function() {
  $("<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>").appendTo("p");
});
body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  margin: 0;
}

nav {
  flex: 0 0 100px;
  background-color: lightgreen;
}

main {
  background-color: orangered;
}

footer {
  flex: 0 0 100px;
  margin-top: auto; /* pin footer to the bottom; see link below for details */
  background-color: lightgray;
}

nav, main, footer {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav>Nav</nav>
<main>
  <p><button id="add">Add Content</button></p>
</main>
<footer>Footer</footer>

revised codepen

有关flex auto margin的更多信息,请参阅以下文章:

答案 3 :(得分:1)

诀窍是使用:

min-height: 100vh; grid-template-rows: auto auto 1fr;与...

align-self: end;(用于页脚)。

如果我们添加左右边距,则将<nav>放在页眉中,为页脚内容添加边距,并为主要内容假定另一个网格:

    body {
        display: grid;
        grid-gap: 1em 0;
        grid: auto auto 1fr / 10vw 1fr 10vw;
        margin: 0;
        min-height: 100vh;
    }

    header {
        grid-column: 2;
    }

    main {
        display: grid;
        grid-column: 2;
    }

    footer {
        align-self: end;
        grid-column: 2;
        margin-bottom: 1em;
    }

这具有以前的解决方案所缺乏的优雅简单性。

使用常绿浏览器,无需使事情复杂化。

以前的答案不太容易维护。陷阱包括:

  • 强制页眉/页脚固定像素大小。
  • 使用网格区域代替简单的网格定义。将网格模板行和网格模板列组合成一个直线有很多好处。
  • 在html和body标签上到处都有广泛的'width / height / min-height:100%'定义。当IE6占据优势但现代浏览器不需要它时,这可能是有道理的。
  • 使用flexbox布局。这不是未来的布局引擎。我想在五年内维护CSS网格。
  • 使用像素和百分比。什么是像素?谁知道什么时候有视网膜屏幕和高分辨率电话屏幕。我曾经喜欢像素,但是还有其他一些更有意义的单位:“ vw / vh / vmin / vmax”加上“ em / rem”。对于CSS网格来说,百分比测量也正在逐步展开,因此最好摆脱这种习惯。

答案 4 :(得分:0)

使用 CSS 网格布局实现粘性页脚的另一个最小起点是使用以下 CSS:

body {
    display: grid;
    grid-template-rows: auto 1fr auto;
    min-height: 100vh;
    margin: 0;
}

设置为 grid-template-rows 的行数为三 (3),因此 <body> 节点内的子元素数必须与此数字匹配。 (根据 OP 问题中列出的 HTML):

<body>
    <header>Header</header>
    <main>
        <p>Video provides a powerful way to help you prove your point.</p>
    </main>
    <footer>Footer</footer>
</body>

OP 引用的原始 CodePen 在 <body> 元素的 CSS 规则中使用相同的属性。它为 .footer 添加了属性设置,但这些设置是不必要的。

正如@Ronnie Royston 在他的回答中指出的那样,min-height: 100vh<body> 元素拉伸到客户端浏览器视口的完整尺寸所必需的。

margin: 0; 删除了大多数浏览器设置的默认边距。

如果未设置 grid-template-columns,CSS 网格布局默认为一列,因此无需在样式规则中设置此属性。

auto 1fr autogrid-template-rows 设置了三行。 auto 的值意味着行的高度将匹配元素内内容的大小。 1fr 的值表示为应用了 auto 的两行之间的元素占用剩余空间。

这允许页眉和页脚在浏览器窗口中应用背景颜色,而@Henry's Cat 添加三列,中间列包含内容。然而,正如他所指出的,避免在网格布局元素的任何大小和间距中使用像素。在页眉或页脚的内容周围使用带有 em/remvw/vh 单位的填充来增加页眉和页脚的高度。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title></title>
    <style>
        body {
            display: grid;
            grid-template-rows: auto 1fr auto;
            min-height: 100vh;
            margin: 0;
        }

        header {
            background-color: #232323;
            color: #fff;
        }

        main {
            background-color: #bbdaf1;
        }

        footer {
            background-color: #8badc6;
        }
    </style>
</head>
<body>
    <header>Header</header>
    <main>
        <p>
            Video provides a powerful way to help you prove your point. When you click Online Video, you can paste in the embed code for the video you want to add. You can also type a keyword to search online for the video that best fits your document.
            To make your document look professionally produced, Word provides header, footer, cover page, and text box designs that complement each other. For example, you can add a matching cover page, header, and sidebar. Click Insert and then choose the elements you want from the different galleries.
            Themes and styles also help keep your document coordinated. When you click Design and choose a new Theme, the pictures, charts, and SmartArt graphics change to match your new theme. When you apply styles, your headings change to match the new theme.
            Save time in Word with new buttons that show up where you need them. To change the way a picture fits in your document, click it and a button for layout options appears next to it. When you work on a table, click where you want to add a row or a column, and then click the plus sign.
            Reading is easier, too, in the new Reading view. You can collapse parts of the document and focus on the text you want. If you need to stop reading before you reach the end, Word remembers where you left off - even on another device.
        </p>
    </main>
    <footer>Footer</footer>
</body>
</html>