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.