首页 > 解决方案 > CSS Grid: Make nav bar collapsible in mobile

问题描述

Trying my best to learn CSS Grid... I have made a nav menu but cannot get it to collapse for mobile view ('hamburger' menu style). I have tried using the 'checkbox hack' seen in several videos and online tutorials. I also can't seem to get all of the links to list (list begins at 'Products' in my mobile view, but should begin at 'About Us').

Been working on this for days with no luck.

If anyone could help me out in getting this to work I would be very grateful.

Here's the HTML & CSS:

html, body{
     margin: 0;
     padding: 0;
     font-family: Roboto, sans-serif;
     font-size: 100%;
}
 header{
    /* grid-column-start: 1;
     grid-column-end: 3;
     grid-row:1;
     */
     grid-area: header;
     background-image:linear-gradient(rgba(0, 0, 0, 0.25), rgba(0, 0, 0, 0.25)), url(../img/rockspiral.jpg);
     display: grid;
     grid-template-columns: repeat (4, 1fr);
    /* 100px, 1fr 1fr 1fr;
    */
    /**** Change to 10% and 90% otherwise it takes up the full viewport ****/
     grid-template-rows: 100px auto;
     grid-template-areas: "logo topbar-nav topbar-nav topbar-nav" ". hero-text hero-text . ";
}
 .logo{
     grid-area: logo;
     background-image:url(../img/logo-mobile.png);
     background-repeat: no-repeat;
     margin-left: 10px;
}
 .topbar-nav{
     grid-area: topbar-nav;
     color:white;
     background-color: lightblue;
     justify-self: end;
     align-self: center;
}
 .topbar-nav, ul, li{
     list-style-type: none;
     float: left;
     padding: 0px 5px 0px 5px;
}
 .hero-text{
     grid-area: hero-text;
     color:white;
     justify-self: center;
     align-self: center;
}
 .hero-text h1{
     font-size: 600%;
}
 .hero-text p{
     font-size: 200%;
     text-align: center;
}
 nav{
     grid-area: nav;
}
 .grid-about{
    /* grid-column-start: 1;
     grid-column-end: 4;
     grid-row:2;
    */
     grid-area: about;
}
 .grid-products{
    /* grid-column-start: 1;
     grid-column-end: 4;
     grid-row:3;
    */
     grid-area: products;
}
 .grid-services{
    /* grid-column-start: 1;
     grid-column-end: 4;
     grid-row:4;
     */
     grid-area: services;
}
 .grid-contact{
     grid-area: contact;
}
 .grid-location{
     grid-area: location;
}
 .grid-phone-social{
     grid-area: phone;
}
 footer{
    /* grid-column-start: 1;
     grid-column-end: 4;
     grid-row:6;
    */
     grid-area: footer;
}
/****Grid for mobile screens****/
 @media (max-width: 767px){
     .grid-container{
         display: grid;
         background-color: aqua;
         grid-auto-rows: 50vh;
         grid-gap: 10px;
         grid-template-areas: "header" 
        /* "nav"*/
         "about" "products" "services" "contact" "location" "phone" "footer";
    }
     header{
         background-image:linear-gradient(rgba(0, 0, 0, 0.25), rgba(0, 0, 0, 0.25)), url(../img/rockspiral-mobile.jpg);
         background-repeat: no-repeat;
        /* Change to: grid-template-columns: 110px auto;
        */
         grid-template-columns: 110px auto;
         grid-template-rows: 50px auto;
         grid-template-areas: "logo topbar-nav" "hero-text hero-text";
    }
     .topbar-nav ul, li{
         display: grid;
         grid-template-rows: 10px;
         grid-gap: 5px;
         font-size:75%;
         float:left;
    }
     .hero-text h1{
         font-size: 300%;
         text-align: center;
    }
     .hero-text p{
         font-size: 150%;
         text-align: center;
    }
}
/****Grid for tablet screens****/
 @media (min-width: 768px){
     .grid-container{
         display: grid;
         grid-auto-rows: 100vh;
         grid-gap: 10px;
         background-color: red;
         grid-template-areas: "header" 
        /* "nav" */
         "about" "products" "services" "contact" "location" "phone" "footer";
    }
     header{
         grid-area: header;
         background-image:linear-gradient(rgba(0, 0, 0, 0.25), rgba(0, 0, 0, 0.25)), url(../img/rockspiral.jpg);
         display: grid;
        /* changed: column size 260px 1fr 1fr 1fr*/
         grid-template-columns: 260px 1fr 1fr 1fr;
         grid-template-rows: 100px auto;
         grid-template-areas: "logo topbar-nav topbar-nav topbar-nav" "hero-text hero-text hero-text hero-text";
    }
     .logo{
         grid-area: logo;
         background-image:url(../img/logo.png);
         background-repeat: no-repeat;
         margin-left: 10px;
    }
}
<!DOCTYPE html>

<html lang=en>

<head>
    <meta charset="utf-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <link rel="stylesheet" href="css/layout.css">

    <link href="https://fonts.googleapis.com/css?family=Roboto&display=swap" rel="stylesheet">

    <title>CSS Grid Sandbox</title>

</head>

<body>

    <div class="grid-container">

        <header>

            <div class="logo"></div>

            <div class="topbar-nav">

                <ul>

                    <li>About</li>
                    <li>Products</li>
                    <li>Services</li>
                    <li>Contact</li>
                    <li>Location & Hours</li>
                    <li>Phone & Social Media</li>

                </ul>

            </div>

            <div class="hero-text">

                <h1>Big Rock Sale</h1>
                <p>All rocks 50% off. Offer ends soon!</p>

            </div>

        </header>

        <!--  <nav>Nav</nav>  -->

        <section class="grid-about">About Us</section>

        <section class="grid-products">Products</section>

        <section class="grid-services">Services</section>

        <section class="grid-contact">Contact</section>

        <section class="grid-location">Location & Hours</section>

        <section class="grid-phone-social">Phone & Social Media</section>

        <footer>Footer</footer>

    </div>

</body>

</html>

标签: htmlcsscss-grid

解决方案


虽然我个人建议为此使用 Javascript,但可以通过多种方法实现纯 CSS 版本,其中一种方法是使用与:checked选择器配对的复选框。

.hamburger-menu-content {
  display: none;
}

#hamburger-menu-trigger:checked+.hamburger-menu-content {
  /* '+' means all elements that have the first element preceding it */
  display: block;
}
<input type="checkbox" id="hamburger-menu-trigger">
<div class="hamburger-menu-content">
  <p>Foo</p>
  <p>Foo</p>
  <p>Foo</p>
</div>

这种方法的缺点是您需要再次单击输入以将其关闭。为了缓解这种情况,我们可以使用一对单选按钮。

.hamburger-menu-content {
  display: none;
}
#hamburger-menu-trigger:checked {
  display: none;
}
#hamburger-menu-trigger:checked+.hamburger-menu-content {
  /* '+' means all elements that have the first element preceding it */
  display: block;
}
<input type="radio" name="menuToggle" id="hamburger-menu-trigger">
<div class="hamburger-menu-content">
  <input type="radio" name="menuToggle">
  <p>Foo</p>
  <p>Foo</p>
  <p>Foo</p>
</div>

编辑:如果您想更改按钮的外观,您可以参考本指南https://www.w3schools.com/howto/howto_css_custom_checkbox.asp


推荐阅读