I need some help making the default Bootstrap carousel look/behave in a certain way.
Here's what I have for now..
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- CSS only -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="carouselExampleControls" class="carousel carousel-dark slide w-75" data-bs-ride="carousel" data-interval="false">
<div class="carousel-inner">
<div class="carousel-item active">
<div class="cards-wrapper">
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
</div>
</div>
<div class="carousel-item">
<div class="cards-wrapper">
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
</div>
</div>
<div class="carousel-item">
<div class="cards-wrapper">
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleControls" data-bs-slide="prev">
<svg viewBox="0 0 40 40"
class="svg-button prev">
<g fill="none" fill-rule="evenodd">
<rect opacity="1" width="38" height="38" rx="20" class="button-arrow"></rect>
<path d="M16.42 9L29 20 16.42 31 15 29.653 26.042 20 15 10.347z"
class="svg-content"></path>
</g>
</svg>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselExampleControls" data-bs-slide="next">
<svg viewBox="0 0 40 40"
class="svg-button">
<g fill="none" fill-rule="evenodd">
<rect opacity="1" width="38" height="38" rx="20" class="button-arrow"></rect>
<path d="M16.42 9L29 20 16.42 31 15 29.653 26.042 20 15 10.347z"
class="svg-content"></path>
</g>
</svg>
</button>
</div>
<!-- JavaScript Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4"
crossorigin="anonymous"></script>
</body>
</html>
CSS (SCSS)
body {
display: flex;
justify-content: center;
align-items: center;
}
.cards-wrapper {
display: flex;
justify-content: center;
align-items: center;
}
.cards-wrapper .card {
margin: 0 4.5rem;
background-color: white;
border: 1px solid black;
width: 12.5%;
height: 250px;
}
.svg-button {
border-radius: 50%;
height: 2.5rem;
width: 2.5rem;
}
.svg-button .button-arrow {
stroke-width: 1px;
stroke: rgb(224, 224, 224);
x: 1;
y: 1;
fill: rgb(255, 255, 255);
transition: fill 250ms ease 0s, opacity 250ms ease 0s;
opacity: 1;
width: 38;
height: 38;
rx: 20;
}
.svg-button .button-arrow:hover {
fill: rgb(224, 224, 224);
}
.svg-button .svg-content {
fill: black;
transition: fill 250ms ease 0s, opacity 250ms ease 0s;
d: path("M 16.42 9 L 29 20 L 16.42 31 L 15 29.653 L 26.042 20 L 15 10.347 Z");
}
.prev {
transform: rotate(-180deg);
}/*# sourceMappingURL=style.css.map */
As you can see the default behavior works, what I was looking for is removing the overlap between the cards (divs in this case) and the buttons once you click them. i tried changing the size of various containers but nothing worked without changing the style drastically, it is probably easier than it seems but I'm just stuck rn.
Curtains stay hidden when .setAttribute("hidden", true); is being used. https://jsfiddle.net/g2th3opc/
evt.currentTarget.closest(".inner-container").querySelector(".sliding-panels").setAttribute("hidden", true);
Curtains don't stay hidden when .classList.add("hide"); is being used. https://jsfiddle.net/06vdjka4/
evt.currentTarget.closest(".inner-container").querySelector(".sliding-panels").classList.add("hide");
To reproduce: Click 1 svg play button, then click the X.
Do that repeatedly, click on all of them, even the ones you already clicked on.
You will notice that the curtains don't stay hidden when .classList.add("hide"); is being used.
The curtains are supposed to stay hidden after clicking on the same svg play button a 2nd time.
Why don't they stay hidden, and is there a fix for that?
I tried to post a snippet but it went over the character limit.
Your issue is the way you are showing the buttons:
function showAllButtons(buttonSelector) {
const allButtons = document.querySelectorAll(buttonSelector);
function showButton(button) {
// This is where the hide class is getting removed
button.classList.remove("hide");
}
allButtons.forEach(showButton);
}
function resetPage() {
resetBackground("body");
resetCurtains(".with-curtain");
// You aren't just matching buttons with this selector. You are matching everything that has been hidden!
showAllButtons(".hide");
resetButtons(".outer");
}
// This is called whenever an exit button is clicked
function exitClickHandler(evt) {
resetPage(); // During this function calls all other .sliding-panels divs are show
// This only hides the current video's .sliding-panels div
evt.currentTarget.closest(".inner-container").querySelector(".sliding-panels").classList.add("hide");
}
The solution is to be more specific with your selector for un-hiding buttons:
// Notice the increased specificity of this selector:
showAllButtons(".container.hide");
const manageUI = (function makeManageUI() {
function resetBackground(backgroundSelector) {
const allBackgrounds = document.querySelectorAll(backgroundSelector);
function showBackground(background) {
background.classList.remove("bg1");
}
allBackgrounds.forEach(showBackground);
}
function resetCurtains(curtainSelector) {
const allCurtains = document.querySelectorAll(curtainSelector);
function showCurtain(curtain) {
curtain.classList.remove("active");
}
allCurtains.forEach(showCurtain);
}
function showAllButtons(buttonSelector) {
const allButtons = document.querySelectorAll(buttonSelector);
function showButton(button) {
button.classList.remove("hide");
}
allButtons.forEach(showButton);
}
function resetButtons(buttonSelector) {
const allButtons = document.querySelectorAll(buttonSelector);
function showButton(button) {
button.classList.remove("isOpen");
}
allButtons.forEach(showButton);
}
function resetPage() {
resetBackground("body");
resetCurtains(".with-curtain");
// Notice the increased specificity of this selector:
showAllButtons(".container.hide");
resetButtons(".outer");
}
function exitClickHandler(evt) {
resetPage();
evt.currentTarget.closest(".inner-container").querySelector(".sliding-panels").classList.add("hide");
}
function addClickToExit(exitButtons) {
exitButtons.forEach(function addExitButtonHandler(exitButtons) {
exitButtons.addEventListener("click", exitClickHandler);
});
}
function init() {
const exitButtons = document.querySelectorAll(".exit");
addClickToExit(exitButtons);
}
return {
init
};
}());
const manageCover = (function makeManageCover() {
const config = {};
function show(el) {
el.classList.remove("hide");
}
function hide(el) {
el.classList.add("hide");
}
function hideAll(elements) {
elements.forEach(hide);
}
function resetBackground(backgroundSelector) {
const allBackgrounds = document.querySelectorAll(backgroundSelector);
function hideBackground(background) {
background.classList.add("bg1");
}
allBackgrounds.forEach(hideBackground);
}
function resetButtons(buttonSelector) {
const allButtons = document.querySelectorAll(buttonSelector);
function hideButton(button) {
button.classList.add("isOpen");
}
allButtons.forEach(hideButton);
}
function resetPage() {
resetBackground("body");
resetButtons(".outer");
}
function markAsPlayed(played) {
played.classList.add("played");
}
function showCovers(playButton) {
const cover = playButton.parentElement;
cover.classList.add("active");
show(cover);
}
function coverClickHandler(evt) {
hideAll(config.containers);
resetPage();
markAsPlayed(evt.currentTarget);
const cover = evt.currentTarget;
showCovers(cover);
}
function addClickToButtons(playButtons) {
playButtons.forEach(function playButtonHandler(playButton) {
playButton.addEventListener("click", coverClickHandler);
});
}
function addCoverHandler(coverSelector, handler) {
const cover = document.querySelector(coverSelector);
cover.addEventListener("click", handler);
}
function init(selectors) {
config.containers = document.querySelectorAll(selectors.container);
const playButtons = document.querySelectorAll(selectors.playButton);
addClickToButtons(playButtons);
}
return {
addCoverHandler,
init
};
}());
function combinePlayerOptions(options1 = {}, options2 = {}) {
const combined = Object.assign({}, options1, options2);
Object.keys(options1).forEach(function checkObjects(prop) {
if (typeof options1[prop] === "object") {
combined[prop] = Object.assign({}, options1[prop], options2[prop]);
}
});
return combined;
}
const videoPlayer = (function makeVideoPlayer() {
const players = [];
const tag = document.createElement("script");
tag.src = "https://www.youtube.com/player_api";
const firstScriptTag = document.getElementsByTagName("script")[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
function createStopHandler(player) {
const stopButtons = document.querySelectorAll(".exit");
stopButtons.forEach(function stopButtonHandler(button) {
button.addEventListener("click", function buttonClickHandler() {
player.stopVideo();
});
});
}
function onPlayerReady(event) {
const player = event.target;
player.setVolume(100);
createStopHandler(player);
}
function addPlayer(video, settings) {
const defaults = {
height: 360,
host: "https://www.youtube-nocookie.com",
videoId: video.dataset.id,
width: 640
};
defaults.events = {
"onReady": onPlayerReady
};
const playerOptions = combinePlayerOptions(defaults, settings);
const player = new YT.Player(video, playerOptions);
players.push(player);
return player;
}
return {
addPlayer
};
}());
const managePlayer = (function makeManagePlayer() {
const defaults = {
playerVars: {
autoplay: 0,
controls: 1,
disablekb: 1,
enablejsapi: 1,
fs: 0,
iv_load_policy: 3
}
};
function show(el) {
el.classList.remove("hide");
}
function createPlayer(videoWrapper, settings = {}) {
const video = videoWrapper.querySelector(".video");
const playerOptions = combinePlayerOptions(defaults, settings);
return videoPlayer.addPlayer(video, playerOptions);
}
function createCoverClickHandler(playerOptions) {
return function coverClickHandler(evt) {
const cover = evt.currentTarget;
const wrapper = cover.nextElementSibling;
show(wrapper);
const player = createPlayer(wrapper, playerOptions);
wrapper.player = player;
};
}
function addPlayer(coverSelector, playerOptions) {
const clickHandler = createCoverClickHandler(playerOptions);
manageCover.addCoverHandler(coverSelector, clickHandler);
}
return {
add: addPlayer
};
}());
function onYouTubeIframeAPIReady() {
managePlayer.add(".playa", {});
managePlayer.add(".playb", {});
managePlayer.add(".playc", {});
managePlayer.add(".playd", {});
managePlayer.add(".playe", {
playerVars: {
playlist: "0dgNc5S8cLI,mnfmQe8Mv1g,-Xgi_way56U,CHahce95B1g"
}
});
managePlayer.add(".playe", {});
managePlayer.add(".playf", {});
managePlayer.add(".playg", {});
managePlayer.add(".playh", {});
managePlayer.add(".playi", {});
manageCover.init({
container: ".container",
playButton: ".thePlay"
});
manageUI.init({});
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
body {
background: #353198;
animation: fade 2s ease 0s forwards;
}
#keyframes fade {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.outer {
display: flex;
flex-wrap: wrap;
min-height: 100%;
width: 290px;
box-sizing: border-box;
justify-content: center;
align-content: center;
margin: auto;
gap: 10px;
}
.outer.isOpen {
display: flex;
width: auto;
align-content: stretch;
}
.container {
display: flex;
justify-content: center;
position: relative;
/*z-index: 2;*/
}
.container.active {
flex: 1 0 0;
}
body.bg1 {
animation: fadebody 5s ease 0s forwards;
}
.thePlay:hover {
box-shadow: 0 0 0 5px rgba(43, 179, 20, 0.5);
}
.thePlay:focus {
outline: 0;
box-shadow: 0 0 0 5px rgba(0, 255, 255, 0.5);
}
.inner-container {
display: none;
}
/* when container is active hide the svg and show the inner container*/
.container.active .thePlay {
display: none;
}
.container.active .inner-container {
display: flex;
}
.container.active .inner-container.curtain {
display: block;
}
#keyframes fadebody {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.thePlay {
width: 90px;
height: 90px;
border-radius: 50%;
cursor: pointer;
border: none;
fill: blue;
background: transparent;
padding: 0;
filter: drop-shadow(3px 3px 3px rgba(0, 0, 0, 0.7));
}
.played {
fill: green;
}
button.thePlay {
pointer-events: none;
}
.exit {
position: absolute;
top: auto;
bottom: -47.63px;
margin: auto;
right: 0;
left: 0;
width: 47.63px;
height: 47.63px;
cursor: pointer;
border: none;
background: transparent;
fill: red;
padding: 0;
}
.exitsvg {
fill: none;
fill-rule: evenodd;
stroke: #ff0000;
stroke-width: 17.80202103;
stroke-linecap: butt;
stroke-linejoin: miter;
stroke-miterlimit: 4;
stroke-dasharray: none;
stroke-opacity: 1;
border: 4.625px solid #4e4e4e;
border-radius: 100%;
}
.curtain {
position: relative;
max-width: 642px;
margin: auto;
flex: 1 0 0%;
background: #0a0a0a;
border: 20px solid #000;
border-radius: 3.2px;
border-color: #000 #101010 #000 #101010;
}
.panel-left,
.panel-right {
position: absolute;
height: 100%;
width: calc(50% + 1px);
/* rounding error fix */
top: 0%;
transition: all ease 10s;
/*background-image: url("https://picsum.photos/600");
background-size: cover;
background-repeat: no-repeat;
background-position: center;*/
overflow: hidden;
}
.panel-left {
left: 0;
/*background-color: rgb(91, 96, 106);*/
}
.panel-right {
right: 0;
/*background-color: rgb(229, 211, 211);*/
}
.panel-left::before,
.panel-right::before {
content: "";
position: absolute;
height: 100%;
width: 200%;
top: 0;
left: 0;
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'> <filter id='filter'> <feTurbulence baseFrequency='0.01 0.0001' numOctaves='5'/> <feColorMatrix values='1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1'/></filter> <rect width='100%' height='100%' filter='url(%23filter)'/> </svg>");
background-size: auto;
background-repeat: no-repeat;
background-position: 0 0;
}
.panel-right::before {
left: -100%;
}
.container.active .curtain .panel-left {
animation: curtain1 8s forwards;
animation-delay: 1s;
}
#keyframes curtain1 {
to {
transform: translateX(-100%);
}
}
.container.active .curtain .panel-right {
animation: curtain2 8s forwards;
animation-delay: 1s;
}
#keyframes curtain2 {
to {
transform: translateX(100%);
}
}
.container.active .curtain .panel-right {
animation: curtain3 8s forwards;
animation-delay: 1s;
}
#keyframes curtain3 {
to {
transform: translateX(100%);
}
}
.container.active .curtain .panel-right {
animation: curtain4 8s forwards;
animation-delay: 1s;
}
#keyframes curtain4 {
to {
transform: translateX(100%);
}
}
.container.active .curtain .panel-right {
animation: curtain5 8s forwards;
animation-delay: 1s;
}
#keyframes curtain5 {
to {
transform: translateX(100%);
}
}
.container.active .curtain .panel-right {
animation: curtain6 8s forwards;
animation-delay: 1s;
}
#keyframes curtain6 {
to {
transform: translateX(100%);
}
}
.container.active .curtain .panel-right {
animation: curtain7 8s forwards;
animation-delay: 1s;
}
#keyframes curtain7 {
to {
transform: translateX(100%);
}
}
.container.active .curtain .panel-right {
animation: curtain8 8s forwards;
animation-delay: 1s;
}
#keyframes curtain8 {
to {
transform: translateX(100%);
}
}
.container.active .curtain .panel-right {
animation: curtain9 8s forwards;
animation-delay: 1s;
}
#keyframes curtain9 {
to {
transform: translateX(100%);
}
}
.ratio-keeper {
position: relative;
height: 0;
padding-top: 56.25%;
margin: auto;
overflow: hidden;
border: 1px solid #333;
}
.video-frame {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.hide {
display: none;
}
<div class="outer">
<div class="container with-curtain">
<button class="playa thePlay" type="button" aria-label="Open">
<svg width="100%" height="100%" viewBox="0 0 64 64">
<g id="play">
<title>Play</title>
<circle cx="32" cy="32" r="32" fill="transparent" pointer-events="visiblePainted" />
<path d="M25.6,46.4L44.8,32L25.6,17.6V46.4z M32,0C14.3,0,0,14.3,0,32s14.3,32,32,32s32-14.3,32-32S49.7,0,32,0z
M32,57.6C17.9,57.6,6.4,46.1,6.4,32S17.9,6.4,32,6.4S57.6,17.9,57.6,32S46.1,57.6,32,57.6z" />
</g>
</svg>
</button>
<div class="inner-container curtain curtain1">
<div class="ratio-keeper">
<div class="wrapa">
<div class="video video-frame" data-id="CHahce95B1g"></div>
</div>
<div class="sliding-panels">
<div class="panel-left"></div>
<div class="panel-right"></div>
</div>
</div>
<button class="exit" type="button" aria-label="Close">
<svg class="exitsvg" width="38.39" height="38.39" viewBox="0 0 100 100">
<g id="exit">
<title>exit</title>
<path d="M 6.3895625,6.4195626 C 93.580437,93.610437 93.580437,93.610437 93.580437,93.610437" />
<path d="M 6.3894001,93.6106 C 93.830213,6.4194003 93.830213,6.4194003 93.830213,6.4194003" />
</g>
</svg>
</button>
</div>
</div>
<div class="container play2 with-curtain">
<button class="playb thePlay" type="button" aria-label="Open">
<svg width="100%" height="100%" viewBox="0 0 64 64">
<use href="#play" />
</svg>
</button>
<div class="inner-container curtain curtain2">
<div class="ratio-keeper">
<div class="wrapa">
<div class="video video-frame" data-id="-Xgi_way56U"></div>
</div>
<div class="sliding-panels">
<div class="panel-left"></div>
<div class="panel-right"></div>
</div>
</div>
<button class="exit" type="button" aria-label="Close">
<svg class="exitsvg" width="38.39" height="38.39" viewBox="0 0 100 100">
<use href="#exit" />
</svg>
</button>
</div>
</div>
<div class="container play3 with-curtain">
<button class="playc thePlay" type="button" aria-label="Open">
<svg width="100%" height="100%" viewBox="0 0 64 64">
<use href="#play" />
</svg>
</button>
<div class="inner-container curtain curtain3">
<div class="ratio-keeper">
<div class="wrapa">
<div class="video video-frame" data-id="-Xgi_way56U"></div>
</div>
<div class="sliding-panels">
<div class="panel-left"></div>
<div class="panel-right"></div>
</div>
</div>
<button class="exit" type="button" aria-label="Close">
<svg class="exitsvg" width="38.39" height="38.39" viewBox="0 0 100 100">
<use href="#exit" />
</svg>
</button>
</div>
</div>
<div class="container play4 with-curtain">
<button class="playd thePlay" type="button" aria-label="Open">
<svg width="100%" height="100%" viewBox="0 0 64 64">
<use href="#play" />
</svg>
</button>
<div class="inner-container curtain curtain4">
<div class="ratio-keeper">
<div class="wrapa">
<div class="video video-frame" data-id="-Xgi_way56U"></div>
</div>
<div class="sliding-panels">
<div class="panel-left"></div>
<div class="panel-right"></div>
</div>
</div>
<button class="exit" type="button" aria-label="Close">
<svg class="exitsvg" width="38.39" height="38.39" viewBox="0 0 100 100">
<use href="#exit" />
</svg>
</button>
</div>
</div>
<div class="container play5 with-curtain">
<button class="playe thePlay" type="button" aria-label="Open">
<svg width="100%" height="100%" viewBox="0 0 64 64">
<use href="#play" />
</svg>
</button>
<div class="inner-container curtain curtain5">
<div class="ratio-keeper">
<div class="wrapa">
<div class="video video-frame"></div>
</div>
<div class="sliding-panels">
<div class="panel-left"></div>
<div class="panel-right"></div>
</div>
</div>
<button class="exit" type="button" aria-label="Close">
<svg class="exitsvg" width="38.39" height="38.39" viewBox="0 0 100 100">
<use href="#exit" />
</svg>
</button>
</div>
</div>
<div class="container play6 with-curtain">
<button class="playf thePlay" type="button" aria-label="Open">
<svg width="100%" height="100%" viewBox="0 0 64 64">
<use href="#play" />
</svg>
</button>
<div class="inner-container curtain curtain6">
<div class="ratio-keeper">
<div class="wrapa">
<div class="video video-frame" data-id="-Xgi_way56U"></div>
</div>
<div class="sliding-panels">
<div class="panel-left"></div>
<div class="panel-right"></div>
</div>
</div>
<button class="exit" type="button" aria-label="Close">
<svg class="exitsvg" width="38.39" height="38.39" viewBox="0 0 100 100">
<use href="#exit" />
</svg>
</button>
</div>
</div>
<div class="container play7 with-curtain">
<button class="playg thePlay" type="button" aria-label="Open">
<svg width="100%" height="100%" viewBox="0 0 64 64">
<use href="#play" />
</svg>
</button>
<div class="inner-container curtain curtain7">
<div class="ratio-keeper">
<div class="wrapa">
<div class="video video-frame" data-id="-Xgi_way56U"></div>
</div>
<div class="sliding-panels">
<div class="panel-left"></div>
<div class="panel-right"></div>
</div>
</div>
<button class="exit" type="button" aria-label="Close">
<svg class="exitsvg" width="38.39" height="38.39" viewBox="0 0 100 100">
<use href="#exit" />
</svg>
</button>
</div>
</div>
<div class="container play8 with-curtain">
<button class="playh thePlay" type="button" aria-label="Open">
<svg width="100%" height="100%" viewBox="0 0 64 64">
<use href="#play" />
</svg>
</button>
<div class="inner-container curtain curtain8">
<div class="ratio-keeper">
<div class="wrapa">
<div class="video video-frame" data-id="-Xgi_way56U"></div>
</div>
<div class="sliding-panels">
<div class="panel-left"></div>
<div class="panel-right"></div>
</div>
</div>
<button class="exit" type="button" aria-label="Close">
<svg class="exitsvg" width="38.39" height="38.39" viewBox="0 0 100 100">
<use href="#exit" />
</svg>
</button>
</div>
</div>
<div class="container play9 with-curtain">
<button class="playi thePlay" type="button" aria-label="Open">
<svg width="100%" height="100%" viewBox="0 0 64 64">
<use href="#play" />
</svg>
</button>
<div class="inner-container curtain curtain9">
<div class="ratio-keeper">
<div class="wrapa">
<div class="video video-frame" data-id="-Xgi_way56U"></div>
</div>
<div class="sliding-panels">
<div class="panel-left"></div>
<div class="panel-right"></div>
</div>
</div>
<button class="exit" type="button" aria-label="Close">
<svg class="exitsvg" width="38.39" height="38.39" viewBox="0 0 100 100">
<use href="#exit" />
</svg>
</button>
</div>
</div>
</div>
Just do this small fix to exit handler.
function exitClickHandler(evt) {
resetPage();
evt.currentTarget
.closest(".inner-container")
.querySelector(".sliding-panels")
.removeAttribute("hidden"); //remove hidden attribute on exit
}
https://jsfiddle.net/h9yfd1nv/
I'm trying to make a carousel, but I am having issues.
First, when you keep clicking the Next button the function keeps on working where it should be stop if the last item is reached. I don't have any idea on how can I tell to the function to stop working. I managed to do it in the prev button though.
Second, I need it to be flexible because I don't know the width nor the count of the items. For example, if there are only two Items, the button Next and Prev is no longer necessary, I want it to hide or something like if the items are no longer fit in the container then show Next or Prev button.
$(document).ready(function() {
var margin_left = 0;
$('#prev').on('click', function(e) {
e.preventDefault();
if (margin_left != 0) {
margin_left = margin_left + 190;
$('ul#csx-chips-menu-slider').animate({
'margin-left': margin_left
}, 300);
}
});
$('#next').on('click', function(e) {
e.preventDefault();
margin_left = margin_left - 190;
$('ul#csx-chips-menu-slider').animate({
'margin-left': margin_left
}, 300);
});
});
* {
box-sizing: border-box;
}
.chips-slider-container {
border: solid 1px;
width: 100%;
padding: 2px;
}
.chips-slider-parent {
width: 100%;
display: flex;
border: solid 1px;
}
.chips-slider-parent .csx-chips-items {
background-color: #CCCCCC;
padding: 5px;
}
.chips-slider-parent .csx-chips-items:nth-child(2) {
background-color: #DDDDDD;
flex: 1;
display: block;
overflow-x: hidden;
}
.csx-chips-menu {
padding: 0;
margin: 0;
list-style: none;
white-space: nowrap;
}
.csx-chips-menu li {
display: inline-block;
padding-left: 10px;
padding-right: 10px;
border: solid 1px;
}
.csx-chips-sub-menu {
display: none;
position: absolute;
background-color: #FFFFFF;
padding: 0;
margin: 0;
margin-left: -11px;
list-style: none;
}
.csx-chips-sub-menu li {
display: block;
}
.csx-chips-menu li:hover>.csx-chips-sub-menu {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="chips-slider-container">
<div class="chips-slider-parent">
<div class="csx-chips-items">
PREV
</div>
<div class="csx-chips-items">
<ul class="csx-chips-menu" id="csx-chips-menu-slider">
<li>
Sample Menu 1
<ul class="csx-chips-sub-menu">
<li>Sample Sub Menu</li>
<li>Sample Sub Menu</li>
<li>Sample Sub Menu</li>
<li>Sample Sub Menu</li>
</ul>
</li>
<li>Sample Menu 2</li>
<li>Sample Menu 3</li>
<li>Sample Menu 4</li>
<li>Sample Menu 5</li>
<li>Sample Menu 6</li>
<li>Sample Menu 7</li>
<li>Sample Menu 8</li>
<li>Sample Menu 9</li>
<li>Sample Menu 10</li>
<li>Sample Menu 11</li>
</ul>
</div>
<div class="csx-chips-items">
NEXT
</div>
</div>
</div>
Here is how I usually do it:
Get the max negative margin by substracting the slider width from the parent width in the getMaxMargin() function. The difference is the maximum offset you can add to the slider.
Then simply use Math.max to make sure to always stay above this limit. And for the other end - to not go above 0 - use Math.min. So the whole magic is this line: margin_left = Math.min(0, Math.max( getMaxMargin(), margin_left + amount ))
$(document).ready(function() {
var margin_left = 0;
$('#prev').on('click', function(e) {
e.preventDefault();
animateMargin( 190 );
});
$('#next').on('click', function(e) {
e.preventDefault();
animateMargin( -190 );
});
const animateMargin = ( amount ) => {
margin_left = Math.min(0, Math.max( getMaxMargin(), margin_left + amount ));
$('ul#csx-chips-menu-slider').animate({
'margin-left': margin_left
}, 300);
};
const getMaxMargin = () =>
$('#csx-chips-menu-slider').parent().width() - $('#csx-chips-menu-slider')[0].scrollWidth;
});
This may help you figure the issue you've got with Next button.
$(document).ready(function(){
$('#btn-nav-previous').click(function(){
$(".menu-inner-box").animate({scrollLeft: "-=100px"});
});
$('#btn-nav-next').click(function(){
$(".menu-inner-box").animate({scrollLeft: "+=100px"});
});
});
nav#menu-container {
background:#586e75;
position:relative;
width:100%;
height: 56px;
}
#btn-nav-previous {
text-align: center;
color: white;
cursor: pointer;
font-size: 24px;
position: absolute;
left: 0px;
padding: 9px 12px;
background: #8f9a9d;
fill:#FFF;
}
#btn-nav-next {
text-align: center;
color: white;
cursor: pointer;
font-size: 24px;
position: absolute;
right: 0px;
padding: 9px 12px;
background: #8f9a9d;
fill:#FFF;
}
.menu-inner-box
{
width: 100%;
white-space: nowrap;
margin: 0 auto;
overflow: hidden;
padding: 0px 54px;
box-sizing: border-box;
}
.menu
{
padding:0;
margin: 0;
list-style-type: none;
display:block;
text-align: center;
}
.menu-item
{
height:100%;
padding: 0px 25px;
color:#fff;
display:inline;
margin:0 auto;
line-height:57px;
text-decoration:none;
text-align:center;
white-space:no-wrap;
}
.menu-item:hover {
text-decoration:underline;
}
.last-item{
margin-right: 50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav id="menu-container" class="arrow">
<div id="btn-nav-previous" style="fill: #FFF">
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32"
viewBox="0 0 24 24">
<path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z" />
<path d="M0 0h24v24H0z" fill="none" />
</svg>
</div>
<div id="btn-nav-next">
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32"
viewBox="0 0 24 24">
<path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" />
<path d="M0 0h24v24H0z" fill="none" />
</svg>
</div>
<div class="menu-inner-box">
<div class="menu">
<a class="menu-item" href="#">Menu 1</a>
<a class="menu-item" href="#">Menu 2</a>
<a class="menu-item" href="#">Menu 3</a>
<a class="menu-item" href="#">Menu 4</a>
<a class="menu-item" href="#">Menu 5</a>
<a class="menu-item" href="#">Menu 6</a>
<a class="menu-item" href="#">Menu 7</a>
<a class="menu-item" href="#">Menu 8</a>
<a class="menu-item" href="#">Menu 9</a>
<a class="menu-item" href="#">Menu 10</a>
<a class="menu-item last-item" href="#">Menu 11</a>
</div>
</div>
</nav>
Notice that I added margin to the last item class.
Credit to Phppot.
EDIT: If you cannot add class to the last item for adding margin on it you can use the following selectors.
:last-of-type
:last-child
e.g.
.two:last-of-type{
color:red;
}
ul :last-child {
color:green;
}
/*These match nothing:*/
.one:last-of-type {
color:pink;
/*.. because li.one is not the last <li>*/
}
.one:last-child {
color: pink;
/*.. because li.one is not the last child*/
}
<ul class="test">
<li class="one">1</li>
<li class="one">2</li>
<li class="one">3</li>
<li class="two">4</li>
<li class="two">This is the last LI type</li>
<dt>This is the last child</dt>
</ul>
Currently I'm making a band-site with HTML. My idea was to have a banner in the -tag where you can click on seperate members to go to there individual page, in an "about us"-page. The basics work, but I have 2 problems.
If I scale the page down the 's are responsive but if I scale up they aren't anymore.
The whole SVG works only on my laptop on any other device it does not work at all.
How can I fix this?
This is the, relevant, code I have right now:
<!DOCTYPE>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
html{
font-family:'Lato', sans-serif;
text-align:center;
background-color:#F1F1F1;
color:#212121;
font-size:1.0875vw;
}
#media screen and (max-width:1150px){
html{
font-size:12.50625px;
}
}
body{
margin:0px;
}
.afbeelding_container{
position:relative;
float:left;
}
.afbeelding_container .tekst_container{
position:absolute;
top:10px;
left:20px;
color:#FFFFFF;
}
.svg_container{
position:absolute;
top:0.625em;
left:1.25em;
}
.MenuButton{
font-size:38px;
cursor:pointer;
color:#F1F1F1;
float:left;
}
#media screen and (max-width:441.92px) {
.MenuButton {
font-size:8.2vw;
}
}
</style>
</head>
<body>
<nav style="width:100%">
<div style="width:100%" class="afbeelding_container">
<img src="Afbeeldingen/Jeopardy Banner 1.jpg" style="width:100%">
<div class="svg_container">
<svg viewBox="0 0 1600 460">
<g class="hover_group" opacity="0">
<a href="maudn.html">
<rect x="195.2" y="54.4" width="228.8" height="405.3" opacity="0.2" fill="#FFFFFF"/>
</a>
</g>
<g class="hover_group" opacity="0">
<a href="maudj.html">
<rect x="448" y="54.4" width="214.4" height="405.3" opacity="0.2" fill="#FFFFFF"/>
</a>
</g>
<g class="hover_group" opacity="0">
<a href="bjorn.html">
<rect x="691.2" y="54.4" width="234.56" height="405.3" opacity="0.2" fill="#FFFFFF"/>
</a>
</g>
<g class="hover_group" opacity="0">
<a href="anne.html">
<rect x="960" y="54.4" width="200" height="405.3" opacity="0.2" fill="#FFFFFF"/>
</a>
</g>
<g class="hover_group" opacity="0">
<a href="merwin.html">
<rect x="1174.4" y="54.4" width="219.52" height="405.3" opacity="0.2" fill="#FFFFFF"/>
</a>
</g>
<a href="https://www.sophiebik.nl">
<rect x="0" y="403" width="100" height="56" style="fill:blue;fill-opacity:0"/>
</a>
</svg>
<div class="tekst_container">
<p><div id="myNav" class="overlay">
×
<div class="overlay-content" style="margin-left:1.vw">
<a href="index.html" >Home</a>
Over ons
Contact
</div>
</div>
<span class="MenuButton" id="MenuButton" onclick="openNav()">☰</span>
<script>
function openNav() {
document.getElementById("myNav").style.width = "100%";
document.getElementById("MenuButton").style.color = "#222";
}
function closeNav() {
document.getElementById("myNav").style.width = "0%";
document.getElementById("MenuButton").style.color = "#F1F1F1";
}
</script>
</p>
</div>
</div>
</div>
</nav>
</body>
</html>
I would suggest abandoning your plan of using a scalable SVG for this and simple allow the box to be sized by your images, and place boxes inside it absolute to align with the image position. The below example is very simple, and once you have your percentage locations and widths, the example will scale up and down perfectly:
header {
position: relative;
width: 80vw;
height: auto;
margin: 0px auto;
}
header img {
width: 100%;
}
header a {
position: absolute;
border: 1px solid red;
}
header a#member1 {
width: 23%;
height: 25%;
top: 25%;
left: 13%;
}
header a#member2 {
width: 13%;
height: 55%;
top: 5%;
left: 43%;
}
header a#member3 {
width: 33%;
height: 15%;
top: 35%;
left: 65%;
}
<header>
<img src="http://placehold.it/900x300" />
Band Member 1
Band Member 2
Band Member 3
</header>
Keep in mind all my values are really just examples, as I have no idea what your actual desired result should look like.
Hi I'm trying to learn how to select image and I've done this so far. I just don't get how to select 2 image at the same time because I already tried removing .removeClass('selected'); in the images_list li function.
HTML:
<div class="images_list">
<li class="border" title="content_1">
<img src="http://www.p69.com.br/wp-content/uploads/2013/04/imagens-lindas-6.jpg?0bce15" width="150" height="150" />
<span>
<img src="http://icons.iconarchive.com/icons/icojam/blue-bits/24/symbol-check-icon.png" />
</span>
</li>
<li class="border" title="content_2">
<img src="http://www.p69.com.br/wp-content/uploads/2013/04/imagens-lindas-6.jpg?0bce15" width="150" height="150" />
<span>
<img src="http://icons.iconarchive.com/icons/icojam/blue-bits/24/symbol-check-icon.png" />
</span>
</li>
</div>
<br><br><br><br><br><br><br><br><br>
<div class="img_info">
<div id="content_1" class="content hidden">content1</div>
<div id="content_2" class="content hidden">content2</div>
</div>
CSS
.images_list li {
list-style: none;
float: left;
width: 150px;
height: 150px;
margin-right: 10px;
}
.images_list li span {
display:none;
position:absolute;
top:0px;
left:0px;
width:24px;
height:24px;
}
.border {
border: 6px solid #D8D8D8;
background: url(upload/check.jpg);
}
.selected {
border: 6px solid green;
position:relative;
}
.hidden {
display:none;
}
.images_list li.selected span {
display:block;
}
JS: here's my JS where I'm having a problem with. I hope somebody can help me, Thanks!
$('.images_list li').click(function() {
$('.images_list .selected').removeClass('selected');
$(this).toggleClass('selected');
var clicked = $(this).attr('title');
$("#"+clicked).removeClass("hidden").siblings().addClass("hidden");
});
you can see my fiddle here: http://jsfiddle.net/jasonc21/59swswz7/
Simply comment out the removeClass line entirely.
$('.images_list li').click(function() {
// Left the following in, in case later you want to make it single again.
// $('.images_list .selected').removeClass('selected');
$(this).toggleClass('selected');
var clicked = $(this).attr('title');
$("#"+clicked).removeClass("hidden").siblings().addClass("hidden");
});
.images_list li {
list-style: none;
float: left;
width: 150px;
height: 150px;
margin-right: 10px;
}
.images_list li span {
display:none;
position:absolute;
top:0px;
left:0px;
width:24px;
height:24px;
}
.border {
border: 6px solid #D8D8D8;
background: url(upload/check.jpg);
}
.selected {
border: 6px solid green;
position:relative;
}
.hidden {
display:none;
}
.images_list li.selected span {
display:block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="images_list">
<li class="border" title="content_1">
<img src="http://www.p69.com.br/wp-content/uploads/2013/04/imagens-lindas-6.jpg?0bce15" width="150" height="150" />
<span>
<img src="http://icons.iconarchive.com/icons/icojam/blue-bits/24/symbol-check-icon.png" />
</span>
</li>
<li class="border" title="content_2">
<img src="http://www.p69.com.br/wp-content/uploads/2013/04/imagens-lindas-6.jpg?0bce15" width="150" height="150" />
<span>
<img src="http://icons.iconarchive.com/icons/icojam/blue-bits/24/symbol-check-icon.png" />
</span>
</li>
</div>
<br><br><br><br><br><br><br><br><br>
<div class="img_info">
<div id="content_1" class="content hidden">content1</div>
<div id="content_2" class="content hidden">content2</div>
</div>