web-dev-qa-db-fra.com

Positionnement du contenu déroulant sous fixe flexbox menu de navigation

J'ai l'extrait suivant (je dois l'afficher en mode plein écran), que j'essaie de placer le <main> élément directement sous le <header> élément. J'ai le <header> dans une position fixe car je veux qu'il reste en haut de l'écran lorsque l'utilisateur fait défiler le contenu dans le <main> élément. J'ai essayé tout ce que je sais, mais le mieux que je puisse trouver est d'avoir le <header> élément placé au-dessus du <main> élément, qui coupe une grande partie du contenu.

La solution la plus proche que j'ai trouvée est de mettre un rembourrage supérieur estimé sur le <main> afin d'effacer l'élément <header>. Cependant, cette solution ne tient pas très bien compte des différentes tailles d'écran, car j'utilise le dimensionnement rem au lieu de px. L'idée de remplissage supérieur est encore pire lorsque vous placez plusieurs éléments à l'intérieur du <header> qui utilisent une hauteur relative ou en pourcentage. Sur une taille d'écran, tout peut s'aligner parfaitement, et sur une taille d'écran différente, le contenu peut être très éloigné.

Enfin, je sais que je peux utiliser jQuery pour définir le remplissage supérieur de manière dynamique, mais cela ne semble pas toujours fonctionner aussi bien. Vous vous demandez s'il existe une solution pure css/html.

Quelqu'un peut-il me dire ce que je manque ici? Ma méthode de rembourrage supérieur est-elle la seule solution viable?

$(document).ready(function() {
  $('#navToggle').click(function() {
    $("div#bottom-container > nav").slideToggle();
  });

  $(window).resize(function() {
      if(window.innerWidth >= "751") {
          $("header > div#bottom-container > nav").show();
      }else {
          $("header > div#bottom-container > nav").hide();
      }
  });

  $("header > div#bottom-container > nav > ul > li > a").click(function(e) {
     if (window.innerWidth <= "750") {
       if ($(this).siblings().size() > 0) {
         e.preventDefault();
         $(this).siblings().slideToggle("slow");
      }
    }
  });

   $("header > div#bottom-container > nav > ul > li").hover(function() {
        if (window.innerWidth >= "751") {
          if ($(this).children("nav").size() > 0) {
            $(this).children("nav").stop().show();
         }
       }
     },function(){
       if (window.innerWidth >= "751") {
         if ($(this).children("nav").size() > 0) {
           $(this).children("nav").hide();
        }
      }
  });
});
* {
  margin: 0;
}

@media (min-width: 48rem) {
  :root {
    font-size: calc(1rem + ((1vw - .48rem) * 1.389));
  }
}

body {
  background: #eee;
  font-family: "HelveticaNeue-Light", Arial;
  height: auto !important;
}

#head-wrap{
    margin: 0 auto;
    position: relative;
    width:100%;
}
#second-wrap{
    position: fixed;
    width:100%;
    z-index:999;
}
main{
  height:4000px;
  position:relative;
  padding-top:13rem;
}

header{
  position: absolute;
  top:0;
  left:0;
  width:100%;
  overflow-x: hidden;
  overflow-y: auto;
  height:200rem;
}

#navToggle {
  background-color: rgba(0, 0, 0, .15);
  position: relative;
  right: 0;
  top: 0;
  z-index:999;
  height: 2.6rem;
}

#navToggle>a {
  color: rgba(255, 255, 255, .85);
  display: block;
  font-size: 0.85em;
  font-weight: 600;
  padding: 0 2.5rem;
  text-decoration: none;
  transition: all 300ms ease;
  padding-top:.9rem;
}

#bottom-container {
  display: flex;
  flex-direction: column;
  text-align: center;
  box-shadow: 2px 5px 10px 1px rgba(0, 0, 0, 0.55);
}

#bottom-container>nav {
  background-color: rgb(250, 209, 14);
  display: none;
  flex: 1;
}

#bottom-container nav>ul {
  list-style-type: none;
}

#bottom-container nav>ul>li {
  position: relative;
}

#bottom-container nav>ul>li>a {
  display: block;
  color: rgba(0, 0, 0, .65);
  padding: 1.3rem 0;
  text-decoration: none;
}

#bottom-container nav>ul>li>a span.toggle {
  background-color: rgba(0, 0, 0, .05);
  color: rgba(0, 0, 0, .25);
  padding: 2px 8px;
}

#bottom-container>nav>ul>li>nav {
  display: none;
  overflow: hidden;
  position: absolute;
  top:100%;
  right: 5%;
  width: 90%;
  z-index: 100;
  background-color: rgb(250, 250, 250);
  margin-bottom:10rem;
}

header>nav>ul>li>nav>ul>li>a {
  color: rgba(255, 255, 255, .85);
}

/*
/////////////////////////////////////////////////
/////////////////////////////////////////////////
////   THIS IS THE ONLY FIX I KNOW OF  //////////
*/
main{
  padding-top:5rem;
}
/*
////////////////////////////////////////////////
////////////////////////////////////////////////
*/

/* Medium screens */
@media all and (min-width: 751px) {
  header{
    overflow-y:visible;
    overflow-x:visible;
    padding-bottom:0;
  }

  #navToggle {
    display: none;
  }

  #bottom-container {
    background-color: rgb(250, 209, 14);
    width: 100%;
    border-top: calc(5vh + 2vw) solid yellow;
  }

  #bottom-container>nav {
    display: block;
  }

  #bottom-container>nav>ul {
    display: flex;
    justify-content: center;
    flex-direction: row;
    height: 3rem;
  }

  #bottom-container nav>ul>li {
    position: static;
    flex:1;
    display: flex;
    justify-content: center;
    align-items: center;
  }

  #bottom-container nav>ul>li>a {
   padding: 0;
  }

  #bottom-container nav>ul>li>a span.toggle {
    display: none;
  }

  #bottom-container >nav>ul>li>nav>ul>li{
    line-height: 2.5rem;
  }
  #bottom-container>nav>ul>li>nav {
    margin-top:-194.5rem;
  }
}
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
</head>
<body>
<div id="head-wrap">
  <div id="second-wrap">
    <header>
      <div id="navToggle"><a href="#">Menu</a></div>
      <div id='bottom-container'>
        <nav>
          <ul>
            <li><a href="#">ITEM ONE</a></li>
            <li class="sub1">
              <a href="#">ITEM TWO <span class="toggle">Expand</span></a>
            <nav>
              <ul>
                <li><a href="#">Sub Item 1</a></li>
                <li><a href="#">Sub Item 2</a></li>
                <li><a href="#">Sub Item 3</a></li>
                <li><a href="#">Sub Item 4</a></li>
              </ul>
            </nav>
            <li><a href="#">ITEM THREE</a></li>
          </ul>
        </nav>
      </div>
    </header>
  </div>
</div>

<main>
  <p>content top not visible but should be able to see</P>
  <p>line 1</P>
  <p>line 2</P>
  <p>line 3</P>
  <p>line 4</P>
  <p>line 5</P>
  <p>line 6</P>
  <p>line 7</P>
  <p>line 8</P>
  <p>line 9</P>
  <p>line 10</P>
    <p>line 11</P>
    <p>line 12</P>
    <p>line 13</P>
    <p>line 14</P>
    <p>line 15</P>
    <p>line 16</P>
    <p>line 17</P>
    <p>line 18</P>
    <p>line 19</P>
    <p>line 20</P>
</main>
</body>
</html>
15
Austin

Je peux vous proposer un Vanilla-JavaScript au lieu de jQuery…

Essayez d'obtenir la taille de "header" lorsque la page se charge (événement onload) et ajoutez-la au remplissage de "main":

window.addEventListener("load", function(e){
  my_main.style.paddingTop = my_header.clientHeight + "px";
}, 1);

afin de travailler, j'ai donné un "id" aux éléments "header" et "main":

<header id="my_header"> <main id="my_main">
window.addEventListener("load", function(e){
  my_main.style.paddingTop = my_header.clientHeight + "px";
}, 1);
* {
    margin: 0;
}
  
@media (min-width: 48rem) {
    :root {
        font-size: calc(1rem + ((1vw - .48rem) * 1.389));
    }
}
  
body {
    background: #eee;
    font-family: "HelveticaNeue-Light", Arial;
    height: auto !important;
 }

header {
    width: 100%;
    position: sticky;
    top: 0;
    box-shadow: 2px 5px 10px 1px rgba(0, 0, 0, 0.55);
}

.wrapper {
    position: relative;
    background-color: rgba(0, 0, 0, .15);
}

#navToggle {
    display: inline-block;
    height: 2.6rem;
}

#navToggle > a {
    color: rgba(255, 255, 255, .85);
    display: block;
    font-size: 0.85em;
    font-weight: 600;
    padding: 0 2.5rem;
    text-decoration: none;
    transition: all 300ms ease;
    padding-top: .9rem;
}

#navToggle:hover + #bottom-container, #bottom-container:hover  {
    visibility: visible;
    opacity: 1;
    transition: all 0.2s ease-in-out;
}

#bottom-container {
    background-color: rgb(250, 209, 14);
    width: 100%;
    visibility: hidden;
    opacity: 0;
    position: absolute;
    top: 100%;
    left: 0;
}

#bottom-container > nav  ul {
    margin: 0;
    padding: 0;
    list-style-type: none;
}

#bottom-container > nav > ul {
    display: flex;
    flex-direction: column;
    flex: 1;
    align-items: center;
}

#bottom-container > nav > ul li {
    display: flex;
    justify-content: center;
    width: 100%;

}

#bottom-container nav > ul > li > a {
    display: block;
    color: rgba(0, 0, 0, .65);
    padding: 1.3rem 0;
    text-decoration: none;
}

.sub1 {
    position: relative;
}

.sub1 > nav {
    position: absolute;
    top: 100%;
    left: 0;
    visibility: hidden;
    opacity: 0;
    background-color: rgb(250, 250, 250);
    width: 100%;
    transition: all 0.2s ease-in-out;
}

.sub1 > nav ul li {
    text-align: center;
}

.sub1 > a:hover + nav, .sub1 > a + nav:hover {
    visibility: visible;
    opacity: 1;
    transition: all 0.2s ease-in-out;
}

#bottom-container nav>ul>li>a span.toggle {
    background-color: rgba(0, 0, 0, .05);
    color: rgba(0, 0, 0, .25);
    padding: 2px 8px;
}

main {
    height:4000px;
}

@media (min-width: 751px){
    #bottom-container > nav > ul {
        flex-direction: row;
        height: 3rem;
    }
    
    #bottom-container nav>ul>li>a span.toggle {
        display: none;
    }
    
    #bottom-container {
        height: 100%;
        border-top: calc(5vh + 2vw) solid yellow;
        visibility: visible;
        opacity: 1;
        position: static;
    }

    #navToggle {
        display: none;
    }
}
<!doctype html>

<html lang="en">

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

    <title></title>

    <link rel="stylesheet" href="styles.css">

</head>

<body>
    <header id="my_header">
        <div class="wrapper">
            <div id="navToggle"><a href="#">Menu</a></div>
            <div id='bottom-container'>
                <nav>
                    <ul>
                        <li><a href="#">ITEM ONE</a></li>
                        <li class="sub1">
                            <a href="#">ITEM TWO <span class="toggle">Expand</span></a>
                            <nav>
                                <ul>
                                    <li><a href="#">Sub Item 1</a></li>
                                    <li><a href="#">Sub Item 2</a></li>
                                    <li><a href="#">Sub Item 3</a></li>
                                    <li><a href="#">Sub Item 4</a></li>
                                </ul>
                            </nav>
                        <li><a href="#">ITEM THREE</a></li>
                    </ul>
                </nav>
            </div>
        </div>
        
    </header>


    <main id="my_main">
        <p>content top not visible but should be able to see</P>
        <p>line 1</P>
        <p>line 2</P>
        <p>line 3</P>
        <p>line 4</P>
        <p>line 5</P>
        <p>line 6</P>
        <p>line 7</P>
        <p>line 8</P>
        <p>line 9</P>
        <p>line 10</P>
        <p>line 11</P>
        <p>line 12</P>
        <p>line 13</P>
        <p>line 14</P>
        <p>line 15</P>
        <p>line 16</P>
        <p>line 17</P>
        <p>line 18</P>
        <p>line 19</P>
        <p>line 20</P>
    </main>
</body>

</html>
0
Federico