Home > Mobile >  How can I make a nav scrolling horizontally with buttons when media queries kick in? html css, javas
How can I make a nav scrolling horizontally with buttons when media queries kick in? html css, javas

Time:10-27

I'm trying to make a nav scrollable but horizontally and with buttons when media queries kicks in. I can't find any solution and it's becoming overwhelming. My team used bootstrap 5.2 and then used scss for styling the project. I think it was the worst mistake we did. We have to replicate EA site and it is starting to look pretty complicated.

I am trying to replicate the same behavior of the "lastest updates" nav when resized. If you scroll down to "latest updates" in this link you can see it: https://www.ea.com/

What I've tried so far:

my HTML with script at the end of the body:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Bootstrap demo</title>
    <link
      href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi"
      crossorigin="anonymous"
    />
    <link rel="stylesheet" href="../css/main.css" />
  </head>
  <body>
    <nav >
      <div >
        <button  id="btn-scroll-left" onclick="scrollHorizontally(1)">I</button>
        <button  id="btn-scroll-right" onclick="scrollHorizontally(-1)">I</button>
      </div>
      <div  id="nav-tab" role="tablist">
        <button
          
          id="nav-notizie-ea-tab"
          data-bs-toggle="tab"
          data-bs-target="#nav-notizie-ea"
          type="button"
          role="tab"
          aria-controls="nav-notizie-ea"
          aria-selected="true"
        >
          <p>Notizie EA</p>
          <hr  />
        </button>
        <button
          
          id="nav-ea-play-tab"
          data-bs-toggle="tab"
          data-bs-target="#nav-ea-play"
          type="button"
          role="tab"
          aria-controls="nav-ea-play"
          aria-selected="false"
        >
          <p>EA Play</p>
          <hr  />
        </button>
        <button
          
          id="nav-fifa-tab"
          data-bs-toggle="tab"
          data-bs-target="#nav-fifa"
          type="button"
          role="tab"
          aria-controls="nav-fifa"
          aria-selected="false"
        >
          <p>FIFA</p>
          <hr  />
        </button>
        <button
          
          id="nav-f1-tab"
          data-bs-toggle="tab"
          data-bs-target="#nav-f1"
          type="button"
          role="tab"
          aria-controls="nav-f1"
          aria-selected="false"
        >
          <p>F1</p>
          <hr  />
        </button>
        <button
          
          id="nav-apex-legends-tab"
          data-bs-toggle="tab"
          data-bs-target="#nav-apex-legends"
          type="button"
          role="tab"
          aria-controls="nav-apex-legends"
          aria-selected="false"
        >
          <p>Apex Legends</p>
          <hr  />
        </button>
        <button
          
          id="nav-the-sims-4-tab"
          data-bs-toggle="tab"
          data-bs-target="#nav-the-sims-4"
          type="button"
          role="tab"
          aria-controls="nav-the-sims-4"
          aria-selected="false"
        >
          <p>The Sims <sup>tm</sup>4</p>
          <hr  />
        </button>
        <button
          
          id="nav-battlefield-tab"
          data-bs-toggle="tab"
          data-bs-target="#nav-battlefield"
          type="button"
          role="tab"
          aria-controls="nav-battlefield"
          aria-selected="false"
        >
          <p>Battlefield</p>
          <hr  />
        </button>
        <button
          
          id="nav-inside-ea-tab"
          data-bs-toggle="tab"
          data-bs-target="#nav-inside-ea"
          type="button"
          role="tab"
          aria-controls="nav-inside-ea"
          aria-selected="false"
        >
          <p>Inside EA</p>
          <hr  />
        </button>
      </div>
    </nav>
    <hr  />
    <div  id="nav-tabContent">
      <div
        
        id="nav-notizie-ea"
        role="tabpanel"
        aria-labelledby="nav-notizie-ea-tab"
        tabindex="0"
      >
        ...
      </div>
      <div
        
        id="nav-ea-play"
        role="tabpanel"
        aria-labelledby="nav-ea-play-tab"
        tabindex="0"
      >
        ...
      </div>
      <div
        
        id="nav-fifa"
        role="tabpanel"
        aria-labelledby="nav-fifa-tab"
        tabindex="0"
      >
        ...
      </div>
      <div
        
        id="nav-f1"
        role="tabpanel"
        aria-labelledby="nav-f1-tab"
        tabindex="0"
      >
        ...
      </div>
      <div
        
        id="nav-apex-legends"
        role="tabpanel"
        aria-labelledby="nav-apex-legends-tab"
        tabindex="0"
      >
        ...
      </div>
      <div
        
        id="nav-the-sims-4"
        role="tabpanel"
        aria-labelledby="nav-the-sims-4-tab"
        tabindex="0"
      >
        ...
      </div>
      <div
        
        id="nav-battlefield"
        role="tabpanel"
        aria-labelledby="nav-battlefield-tab"
        tabindex="0"
      >
        ...
      </div>
      <div
        
        id="nav-inside-ea"
        role="tabpanel"
        aria-labelledby="nav-inside-ea-tab"
        tabindex="0"
      >
        ...
      </div>
    </div>
    <script
      src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
      integrity="sha384-OERcA2EqjJCMA /3y gxIOqMEjwtxJY7qPCqsdltbNJuaOe923 mo//f6V8Qbsw3"
      crossorigin="anonymous"
    ></script>
    <script>
      let currentScrollPosition = 0;
      let scrollAmount = 50;

      const navCont = document.querySelector(".nav");
      const horizontalScroll = document.querySelector(".scroll-horizontal");
      const btnScrollLeft = document.querySelector("#btn-scroll-left");
      const btnScrollRight = document.querySelector("#btn-scroll-right");

      let maxScroll= -navCont.offsetWidth   horizontalScroll.offsetWidth;

      function scrollHorizontally(val){
        currentScrollPosition  = (val * scrollAmount); 
        
        if(currentScrollPosition > 0){
           currentScrollPosition = 0;
        }

        // if(currentScrollPosition < maxScroll){
        //    currentScrollPosition = maxScroll;
        // }
        
        navCont.style.left = currentScrollPosition   "px";          
      }
    </script>
  </body>
</html>

My SCSS:

@import "../abstracts/colors";

  .scroll-horizontal {
    width: 100%;
    display: none;
    z-index: 1;
    justify-content: space-between;
  }

  .nav::-webkit-scrollbar {
    display: none;
  }

  .nav {
    flex-wrap: nowrap;
    border-bottom: 0px solid var(--gray);
    flex-shrink: 0;
    // overflow: hidden;
    position: relative;
    transition: 0.1s all ease-out;

    #nav-tab {

      position: relative;
    }

    .nav-link {
      height: 3.5rem;
      position: relative;
      color: black;
      border-radius: 0%;
      padding-left: 0px;
      padding-right: 0px;
      border: 0px;
      flex-shrink: 0;
      transition: 1s all ease-out;

      .button-hr {
        border: 0px;
        width: 85%;
        height: 2px;
        opacity: 1;
        background-color: var(--orange);
        position: absolute;
        bottom: -27%;
        left: 7%;
        visibility: hidden;
        flex-shrink: 0;
      }

      p {
        width: 100%;
        padding-inline: 1rem;
        margin-bottom: 0px;
        border-left: 1px solid var(--gray-focus);
        border-right: 1px solid var(--gray-focus);
        flex-shrink: 0;
      }

      &:nth-of-type(1) p {
        border-left: none;
      }

      &:last-of-type p {
        border-right: none;
      }

      &:hover {
        background-color: transparentize(($gray-focus), 0.5);
      }
    }
    .nav-link.active {
      color: black, 0.5;
      background-color: transparentize(($gray-focus), 0.5);
      border-radius: 0%;
      .button-hr {
        visibility: visible;
        animation: myanimation 0.1s;
      }
    }
  }

  .nav-hr {
    opacity: 1;
    margin: 0px;
    border-top: 2px solid var(--gray-focus);
    flex-shrink: 0;
    margin-bottom: 3rem;
  }

  @keyframes myanimation {
    from {
      width: 1%;
      left: 50%;
    }
    to {
      width: 85%;
      left: 7%;
    }
  }

  @media screen and (max-width:808px) {
    .scroll-horizontal {
      width: 100%;
      display: flex;
      z-index: 1;
      justify-content: space-between;
    }
    
  }

CodePudding user response:

You are probably going to need a horizontal scroll javascript plugin. Focus on getting the slider working first and then worry about hiding the arrows on desktop using media queries.

I can't really recommend a plugin but something lightweight like this? https://nickpiscitelli.github.io/Glider.js/

or something more feature rich like this? https://swiperjs.com/demos

CodePudding user response:

I wrote totally new codes. I used swiper slider to slide nav links at for example md resolution. This is my code:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <title>Swiper-bootstrap-nav</title>
  <meta
          name="viewport"
          content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1"
  />

  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">

  <!-- Link Swiper's CSS -->
  <link
          rel="stylesheet"
          href="https://cdn.jsdelivr.net/npm/swiper/swiper-bundle.min.css"
  />

  <!-- Demo styles -->
  <style>
    html,
    body {
      position: relative;
      height: 100%;
    }

    body {
      background: #eee;
      font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
      font-size: 14px;
      color: #000;
      margin: 0;
      padding: 0;
    }

    .swiper, .navbar {
      width: 90%;
      height: 80px;
    }

    .swiper-slide {
      text-align: center;
      font-size: 18px;
      background: #D35;

      /* Center slide text vertically */
      display: -webkit-box;
      display: -ms-flexbox;
      display: -webkit-flex;
      display: flex;
      -webkit-box-pack: center;
      -ms-flex-pack: center;
      -webkit-justify-content: center;
      justify-content: center;
      -webkit-box-align: center;
      -ms-flex-align: center;
      -webkit-align-items: center;
      align-items: center;
    }

    .swiper-slide img {
      display: block;
      width: 100%;
      height: 100%;
      object-fit: cover;
    }

    .swiper-slide {
      width: 18%;
    }

    .swiper-button-next, .swiper-button-prev {
      color: #055025;
    }

  </style>
</head>

<body>
<div >
  <div >
    <div >
      <div >
        <nav >
          <div >
            <div>
              <button >link-1</button>
            </div>
            <div>
              <button >link-2</button>
            </div>
            <div>
              <button >link-3</button>
            </div>
            <div>
              <button >link-4</button>
            </div>
            <div>
              <button >link-5</button>
            </div>
            <div>
              <button >link-6</button>
            </div>
            <div>
              <button >link-7</button>
            </div>
            <div>
              <button >link-8</button>
            </div>
            <div>
              <button >link-9</button>
            </div>
          </div>
        </nav>
      </div>
      <!-- slider nav is shown at "md" and below resolutions -->
      <div >
        <div >
          <div >

            <button >link-1</button>

            <button >link-2</button>

            <button >link-3</button>

            <button >link-4</button>

            <button >link-5</button>

            <button >link-6</button>

            <button >link-7</button>

            <button >link-8</button>

            <button >link-9</button>

          </div>
          <div ></div>
          <div ></div>
        </div>

      </div>
    </div>
  </div>
</div>

<!-- Swiper JS -->
<script src="https://cdn.jsdelivr.net/npm/swiper/swiper-bundle.min.js"></script>

<!-- Initialize Swiper -->
<script>
  var swiper = new Swiper(".mySwiper", {
    slidesPerView: "auto",
    spaceBetween: 20,
    navigation: {
      nextEl: ".swiper-button-next",
      prevEl: ".swiper-button-prev",
    },
  });
</script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA /3y gxIOqMEjwtxJY7qPCqsdltbNJuaOe923 mo//f6V8Qbsw3" crossorigin="anonymous"></script>
</body>
</html>

You can test it at md resolution by changing the window width in your development environment. That is for solving the main problem of the question (nav sliding horizontally with buttons when media queries kick in). You must link the related content to each button. Also you may need to change styles according to your design.

  • Related