I am trying to achieve a "next page" slide animation in CSS and Javascript. If user clicks a div page, the current page move left and fade out and next page will replace the current container.
This is what I tried, but I don't know how to change container to have dimensions based on current page.
(function () {
document.querySelectorAll(".page").forEach((item, idx) => {
if (idx !== 0) {
item.classList.add("hidden");
item.style.maxHeight = 0;
} else {
}
});
document.querySelectorAll(".page").forEach((item) => {
item.addEventListener("click", (event) => {
const currentPage = event.target.closest(".page");
const nextPage = currentPage.nextElementSibling;
nextPage.style.maxHeight = "1000px";
nextPage.classList.add("show-page");
currentPage.classList.add("hide-page");
});
});
})();
.container {
font-family: inherit;
position: fixed;
bottom: 40px;
right: 40px;
background-color: #eb6383;
width: 300px;
padding: 10px;
display: flex;
flex-direction: column;
overflow: hidden;
}
.page {
display: flex;
flex-direction: column;
transition: 1s;
left: 0%;
opacity: 1;
position: relative;
background-color: yellow;
}
.hidden {
position: relative;
overflow: hidden;
left: 100%;
transition: 1s;
}
.show-page {
position: relative;
left: 0%;
transition: 1s;
}
.hide-page {
opacity: 0;
left: -100%;
transition: 1s;
}
<div class="container">
<div class="page">
<div class="Header">page 1</div>
<div class="Content">
content page 1
</div>
</div>
<div class="page">
<div class="Header">page 2</div>
<div class="Content">
content page 2
</div>
</div>
<div class="page">
<div class="Header">page 3</div>
<div class="Content">
content page 3
</div>
</div>
</div>
Instead of moving each slide on it's own, we can animate a parent element holding all the slides
Here's a simplified version.
(function() {
let slides = document.querySelectorAll('.page');
let slidesCount = slides.length
let index = 0; // index
slides.forEach(slide => {
slide.onclick = (e) => {
/* Logic */
let nextIndex = (++index % slidesCount);
/* End Logic */
/* Management for the CSS */
// By how much we want to move, In Percents.
// A negative value because we're moving left
let ditance = -100;
// If nextIndex = 2, Then rawCssValue = -200
let styleValue = nextIndex * ditance;
/* Applying the CSS */
let style = `translateX(${styleValue}%)`;
e.target.parentElement.style.transform = style;
}
});
})()
.container {
font-family: inherit;
position: fixed;
bottom: 40px;
right: 40px;
width: 300px;
background: #eb6383;
overflow: hidden;
}
.page {
display: flex;
transition: 1s;
left: 0%;
opacity: 1;
position: relative;
background-color: yellow;
}
/* New */
.page {
flex: 0 0 auto;
height: 100%;
width: 100%;
}
.page + .page {
margin-left: 20px;
}
.slide {
padding: 10px;
box-sizing: border-box;
height: 100%;
display: flex;
flex-wrap: nowrap;
background: #eb6383;
transition: all .5s linear;
transform: translateX(0);
}
<div class="container">
<div class="slide">
<div class="page">
<div class="Header">page 1</div>
<div class="Content">
content page 1
</div>
</div>
<div class="page">
<div class="Header">page 2</div>
<div class="Content">
content page 2
</div>
</div>
<div class="page">
<div class="Header">page 3</div>
<div class="Content">
content page 3
</div>
</div>
<div class="page">
<div class="Header">page 4</div>
<div class="Content">
content page 4
</div>
</div>
</div>
</div>
I recommend using buttons for navigating through the slider, clicking the page to the move will become problematic very quick Because the children consume the event.
Related
I have an automatic sliding carousel which is working fine except that when it reach the last image then it just freeze on the last image instead of auto slide to the first image. I just can't remake my javascript code alone. Strange but autosliding to the first image was working a few months ago. I had nothing change to the code but seems after last updates of chrome its just not working correctly neither on pc neither on mobile devices. Here is my javascript code:
const carousels = document.querySelectorAll('.img-carousel');
const prevBtn = document.querySelectorAll('.prev');
const nextBtn = document.querySelectorAll('.next');
let carsouselImages = document.querySelectorAll('.img-carousel div');
//Next Carousel
carousels.forEach((carousel, index)=>{
const nextCarousel = () => {
if(carsouselImages[carsouselImages.length - 1]) {
carousel.scrollTo(0, 0);
}
carousel.scrollBy(300, 0);
};
nextBtn[index].addEventListener('click', e => {
nextCarousel();
});
//Prev Carousel
const prevCarousel = () => {
if(carsouselImages[0]) {
carousel.scrollTo(4800,0);
}
carousel.scrollBy(-300, 0);
};
prevBtn[index].addEventListener('click', e => {
prevCarousel();
});
// Auto carousel
const auto = true; // Auto scroll
const intervalTime = 5000;
let sliderInterval;
if (auto) {
sliderInterval = setInterval(nextCarousel, intervalTime);
};
carousel.addEventListener('mouseover', (stopInterval) => {
clearInterval(sliderInterval);
});
carousel.addEventListener('mouseleave', (startInterval) => {
if (auto) {
sliderInterval = setInterval(nextCarousel, intervalTime);
}
});
//for mobile events
carousel.addEventListener('touchstart', (stopIntervalT) => {
clearInterval(sliderInterval);
});
carousel.addEventListener('touchend', (startIntervalT) => {
if (auto) {
sliderInterval = setInterval(nextCarousel, intervalTime);
}
});
//Debounce
var previousCall;
window.addEventListener('resize', () => {
if (previousCall >= 0) {
clearTimeout(previousCall);
}
});
});
Here are css and html codes if needed:
/** img-carousel **/
#imgages-carousel {
display: grid;
align-items: center;
justify-items: center;
padding: 40px 0px;
}
#imgages-carousel1 {
display: grid;
align-items: center;
justify-items: center;
padding: 40px 0px;
}
.img-carousel-container {
width: 800px;
position: relative;
}
.img-carousel {
display: flex;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
scroll-snap-type: x mandatory;
scroll-behavior: smooth;
padding-bottom: 5px;
}
.img-carousel div {
flex: none;
scroll-snap-align: start;
width: 800px;
position: relative;
}
.img-carousel div img {
display: block;
width: 100%;
object-fit: cover;
}
.img-carousel div p {
position: absolute;
top: 0;
right: 10px;
background: rgba(0,0,0,0.5);
color: #fff;
padding: 5px;
border-radius: 10px;
}
.img-carousel-container button {
position: absolute;
top: calc(50% - 15px);
transform: translateY(-50%);
border: none;
background-color: rgba(255, 193, 7, 0.7);
color: #000;
cursor: pointer;
padding: 10px 15px;
border-radius: 50%;
outline: none;
opacity: 0;
transition: all ease-in-out 0.5s;
}
.prev {
left: 10px;
}
.next {
right: 10px;
}
.img-carousel-container:hover button {
opacity: 1;
}
.img-carousel-container button:hover {
background-color: #ffc107;
}
/** custom scrollbar **/
.img-carousel::-webkit-scrollbar {
width: 10px;
height: 10px;
}
.img-carousel::-webkit-scrollbar-thumb {
background: #ffc107;
border-radius: 10px;
}
.img-carousel::-webkit-scrollbar-track {
background: transparent;
}
.img-carousel-container:hover .img-carousel::-webkit-scrollbar-thumb {
visibility: visible;
}
#media screen and (max-width: 800px) {
.img-carousel-container {
width: 100%;
}
.img-carousel div {
width: 100%;
}
}
html:
<!-- section images carousel -->
<section id="imgages-carousel">
<div class="img-carousel-container">
<div class="img-carousel">
<div>
<img src="https://source.unsplash.com/9Nok_iZEgLk/800x450">
<p>1/6</p>
</div>
<div>
<img src="https://source.unsplash.com/4v7ubW7jz1Q/800x450">
<p>2/6</p>
</div>
<div>
<img src="https://source.unsplash.com/rtCujH697DU/800x450">
<p>3/6</p>
</div>
<div>
<img src="https://source.unsplash.com/ELv8fvulR0g/800x450">
<p>4/6</p>
</div>
<div>
<img src="https://source.unsplash.com/LoPGu6By90k/800x450">
<p>5/6</p>
</div>
<div>
<img src="https://source.unsplash.com/Ndz3w6MCeWc/800x450">
<p>6/6</p>
</div>
</div>
<button class="prev"><i class="fas fa-chevron-left fa-2x"></i></button>
<button class="next"><i class="fas fa-chevron-right fa-2x"></i></button>
</div>
</section>
<section id="imgages-carousel1">
<div class="img-carousel-container">
<div class="img-carousel">
<div>
<img src="https://source.unsplash.com/9Nok_iZEgLk/800x450">
<p>1/6</p>
</div>
<div>
<img src="https://source.unsplash.com/4v7ubW7jz1Q/800x450">
<p>2/6</p>
</div>
<div>
<img src="https://source.unsplash.com/rtCujH697DU/800x450">
<p>3/6</p>
</div>
<div>
<img src="https://source.unsplash.com/ELv8fvulR0g/800x450">
<p>4/6</p>
</div>
<div>
<img src="https://source.unsplash.com/LoPGu6By90k/800x450">
<p>5/6</p>
</div>
<div>
<img src="https://source.unsplash.com/Ndz3w6MCeWc/800x450">
<p>6/6</p>
</div>
</div>
<button class="prev"><i class="fas fa-chevron-left fa-2x "></i></button>
<button class="next"><i class="fas fa-chevron-right fa-2x "></i></button>
</div>
</section>
Given two rows of cards, I'm trying to combine the following animations:
Move the first card on the first row over the second card on the second row.
This is done by changing the top and left style properties.
Flip the first card on the first row.
I'm flipping the card based on this w3schools example.
Move the second card on the first row to the left.
The card is moved to the left by giving the div next to it zero width.
Animation 3) seems to conflict with animation 2).
Normally, a 'flip' involves swapping the front facing div with the back facing div.
However, when animation 3) gives the parent div zero width, the front and back are no longer aligned and both sides can be seen.
The following snippet demonstrates that a 'flip' seems to work, while 'move and flip' goes wrong.
Can you help me fix this such that all animations work correctly together?
function flipCard() {
const flipCard = document.querySelector('.top .flip-card')
const rect = flipCard.getBoundingClientRect()
flipCard.classList.add('moving')
flipCard.classList.add('flipped')
return [flipCard, rect]
}
function moveFlipCard() {
const srcSleeve = document.querySelector('.top .sleeve')
srcSleeve.classList.add('closed')
const [srcFlipCard, srcRect] = flipCard()
const targetFlipCard = document.querySelectorAll('.bottom .sleeve')[1]
const targetRect = targetFlipCard.getBoundingClientRect()
const offset = {
top: targetRect.top - srcRect.top,
left: targetRect.left - srcRect.left,
}
srcFlipCard.style.top = offset.top + 'px'
srcFlipCard.style.left = offset.left + 'px'
}
const flipButton = document.getElementById('flipCard')
flipButton.addEventListener('click', flipCard)
const moveFlipButton = document.getElementById('moveFlipCard')
moveFlipButton.addEventListener('click', moveFlipCard)
* {
font-family: sans-serif;
font-size: 24px;
}
.cards {
display: flex;
position: relative;
}
.sleeve {
position: relative;
width: 60px;
height: 76px;
transition: width 1s;
}
.sleeve.closed {
width: 0;
}
.card {
position: relative;
width: 50px;
height: 70px;
border: 3px solid black;
border-radius: 5px;
display: flex;
text-align: center;
align-items: center;
justify-content: center;
font-size: 24px;
margin: 0 2px;
transition: top 1s, left 1s;
}
.card.closed {
background-color: rgb(125, 171, 250);
color: black;
}
.card.open {
background-color: rgb(218, 218, 218);
}
.card.black {
color: black;
}
.card.red {
color: red;
}
/* Based on https://www.w3schools.com/howto/howto_css_flip_card.asp */
.flip-card {
position: relative;
perspective: 1000px;
transition: top 1s, left 1s;
}
.flip-card-inner {
position: relative;
width: 100%;
height: 100%;
transition: transform 1s;
transform-style: preserve-3d;
}
.flip-card.flipped .flip-card-inner {
transform: rotateY(180deg);
}
.flip-card-front,
.flip-card-back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
}
.flip-card-back {
transform: rotateY(180deg);
}
.flip-card.moving {
z-index: 1;
}
<div id="app">
<div class="top cards">
<div class="sleeve">
<div class="flip-card" style="top: 0; left: 0;">
<div class="flip-card-inner">
<div class="flip-card-front">
<div class="card open black">A♣</div>
</div>
<div class="flip-card-back">
<div class="card closed">?</div>
</div>
</div>
</div>
</div>
<div class="sleeve">
<div class="flip-card" style="top: 0; left: 0;">
<div class="flip-card-inner">
<div class="flip-card-front">
<div class="card open black">2♣</div>
</div>
<div class="flip-card-back">
<div class="card closed">?</div>
</div>
</div>
</div>
</div>
</div>
<div class="bottom cards">
<div class="sleeve">
<div class="flip-card">
<div class="flip-card-inner">
<div class="flip-card-front">
<div class="card open red">5♥</div>
</div>
<div class="flip-card-back">
<div class="card closed">?</div>
</div>
</div>
</div>
</div>
<div class="sleeve">
<div class="flip-card">
<div class="flip-card-inner">
<div class="flip-card-front">
<div class="card open red">6♥</div>
</div>
<div class="flip-card-back">
<div class="card closed">?</div>
</div>
</div>
</div>
</div>
</div>
<button id="flipCard">flip</button>
<button id="moveFlipCard">move and flip</button>
</div>
TLDR: To solve this, I explicitly set transform-origin: 30px 0 0. Now the point around which a transformation is applied no longer depends on the size of the bounding box.
I now see where it goes wrong. The problem lies with the transform-origin.
The transform origin is the point around which a transformation is applied.
For animation 2) this corresponds to the point around which the card is rotated 180 degrees over the y-axis (transform: rotateY(180deg)).
The default value of the transform-origin property is 50% 50% 0, where the values correspond to the offset over the x-axis, y-axis and z-axis, respectively.
However, what does 50% mean? 50% of what?
Percentages refer to the size of bounding box
So, what's the bounding box of the flipped div? When I inspect <div class="flip-card-inner"> I see it has a dimensions 60x0:
where 60 corresponds to width: 60px of parent <div class="sleeve">.
So for <div class="flip-card-inner"> the default transform-origin is 30px 0 0. This is what I expect: the card rotates over its y-axis at a point that lies halfway over the x-axis, such that the card is in the same location when flipped.
Now let's see what happens when we apply animation 3), i.e. move the second card on the first row to the left by giving the div next to it zero width:
Now the bounding box is 0x0, because the parent <div class="sleeve closed"> has zero width. Since the bounding box has changed, so has the transform-origin: 50% of 0 is 0, so we get 0 0 0. The card now rotates over its y-axis at a point that lies on the left side of the card. This has the undesired effect that the flipped card does not end up at the same location as where it started.
To solve this, I explicitly set transform-origin: 30px 0 0. Now the point around which a transformation is applied no longer depends on the size of the bounding box.
Working example:
function flipCard() {
const flipCard = document.querySelector('.top .flip-card')
const rect = flipCard.getBoundingClientRect()
flipCard.classList.add('moving')
flipCard.classList.add('flipped')
return [flipCard, rect]
}
function moveFlipCard() {
const srcSleeve = document.querySelector('.top .sleeve')
srcSleeve.classList.add('closed')
const [srcFlipCard, srcRect] = flipCard()
const targetFlipCard = document.querySelectorAll('.bottom .sleeve')[1]
const targetRect = targetFlipCard.getBoundingClientRect()
const offset = {
top: targetRect.top - srcRect.top,
left: targetRect.left - srcRect.left,
}
srcFlipCard.style.top = offset.top + 'px'
srcFlipCard.style.left = offset.left + 'px'
}
const flipButton = document.getElementById('flipCard')
flipButton.addEventListener('click', flipCard)
const moveFlipButton = document.getElementById('moveFlipCard')
moveFlipButton.addEventListener('click', moveFlipCard)
* {
font-family: sans-serif;
font-size: 24px;
}
.cards {
display: flex;
position: relative;
}
.sleeve {
position: relative;
width: 60px;
height: 76px;
transition: width 1s;
}
.sleeve.closed {
width: 0;
}
.card {
position: relative;
width: 50px;
height: 70px;
border: 3px solid black;
border-radius: 5px;
display: flex;
text-align: center;
align-items: center;
justify-content: center;
font-size: 24px;
margin: 0 2px;
transition: top 1s, left 1s;
}
.card.closed {
background-color: rgb(125, 171, 250);
color: black;
}
.card.open {
background-color: rgb(218, 218, 218);
}
.card.black {
color: black;
}
.card.red {
color: red;
}
/* Based on https://www.w3schools.com/howto/howto_css_flip_card.asp */
.flip-card {
position: relative;
perspective: 1000px;
transition: top 1s, left 1s;
}
.flip-card-inner {
position: relative;
width: 100%;
height: 100%;
transition: transform 1s;
transform-style: preserve-3d;
}
.flip-card.flipped .flip-card-inner {
transform-origin: 30px 0 0;
transform: rotateY(180deg);
}
.flip-card-front,
.flip-card-back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
}
.flip-card-back {
transform-origin: 30px 0 0;
transform: rotateY(180deg);
}
.flip-card.moving {
z-index: 1;
}
<div id="app">
<div class="top cards">
<div class="sleeve">
<div class="flip-card" style="top: 0; left: 0;">
<div class="flip-card-inner">
<div class="flip-card-front">
<div class="card open black">A♣</div>
</div>
<div class="flip-card-back">
<div class="card closed">?</div>
</div>
</div>
</div>
</div>
<div class="sleeve">
<div class="flip-card" style="top: 0; left: 0;">
<div class="flip-card-inner">
<div class="flip-card-front">
<div class="card open black">2♣</div>
</div>
<div class="flip-card-back">
<div class="card closed">?</div>
</div>
</div>
</div>
</div>
</div>
<div class="bottom cards">
<div class="sleeve">
<div class="flip-card">
<div class="flip-card-inner">
<div class="flip-card-front">
<div class="card open red">5♥</div>
</div>
<div class="flip-card-back">
<div class="card closed">?</div>
</div>
</div>
</div>
</div>
<div class="sleeve">
<div class="flip-card">
<div class="flip-card-inner">
<div class="flip-card-front">
<div class="card open red">6♥</div>
</div>
<div class="flip-card-back">
<div class="card closed">?</div>
</div>
</div>
</div>
</div>
</div>
<button id="flipCard">flip</button>
<button id="moveFlipCard">move and flip</button>
</div>
Hello guys I want my animation be infinite and when it finish - he restart without any jump space.
and moreover allow to click event to go next position on my animation circle
How can I apply it?
let jump = 0;
let index = 0;
const boxContainer = document.querySelector(".boxContainer");
const animate = () => {
boxContainer.style.transform = `translate(${jump}px)`;
boxContainer.appendChild(boxContainer.children[index].cloneNode(true));
index++;
};
const nextBox = () => {
jump -= 100;
requestAnimationFrame(animate);
};
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.container {
background-color: aqua;
height: fit-content;
width: 500px;
overflow-x: hidden;
position: relative;
}
.anim {
animation: anim 10s infinite linear;
}
.boxContainer {
display: flex;
transition: transform 0.2s;
}
.boxContainer > .box {
width: 90px;
height: 90px;
margin: 5px;
background-color: blue;
flex-shrink: 0;
display: flex;
justify-content: center;
align-items: center;
color: white;
}
.container > button {
position: absolute;
left: 0px;
top: 32px;
width: 50px;
}
#keyframes anim {
to {
transform: translateX(-1000px);
}
}
<div class="container">
<div class="anim">
<div class="boxContainer">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
<div class="box">7</div>
<div class="box">8</div>
<div class="box">9</div>
<div class="box">10</div>
<div class="box">11</div>
<div class="box">12</div>
<div class="box">13</div>
<div class="box">14</div>
<div class="box">15</div>
<div class="box">16</div>
</div>
</div>
<button onclick="nextBox()">next box</button>
</div>
As you can see I create at animation that allow that click event nad he jump to next position but in some place animation restart in wrong place.
How to fix that issue in right and performance way ?
i gave each div containing a slide of my slider a property position of value absolute and it hides elements following it.
basically i created a main tag with a section tag for the slider and another for the features section now because i gave position: absolute to the div with class slide the features section is invisible as it is hidden behind the slider section.
how can i fix this so that i can add other sections to my page and they appear properly following each other and not stacked or hiding behind each other like this.
please let me know if i don't get the real reason why this problem happened.
var slides = document.querySelectorAll('.sliderContainer .slide'),
slideCount = slides.length,
currentSlide = 1;
var paginationElement = document.createElement('ul');
paginationElement.setAttribute('id', 'paginationUl');
for (var i = 0; i < slideCount; i++) {
paginationItem = document.createElement('li');
paginationItem.setAttribute('data-index', i);
paginationElement.appendChild(paginationItem);
// paginationItem.appendChild(document.createTextNode(i));
}
var indicators = document.getElementById('indicators');
indicators.appendChild(paginationElement);
var paginationUL = document.getElementById('paginationUl'),
paginationBullets = Array.from(document.querySelectorAll('#paginationUl li'));
for (var i = 0; i < paginationBullets.length; i++) {
paginationBullets[i].onclick = function() {
currentSlide = parseInt(this.getAttribute('data-index'));
console.log(currentSlide);
checker();
}
}
checker();
function checker() {
removeActive();
slides[currentSlide].classList.add('active');
paginationBullets[currentSlide].classList.add('active');
}
function removeActive() {
slides.forEach(function(slide) {
slide.classList.remove('active');
});
paginationBullets.forEach(function(bullet) {
bullet.classList.remove('active');
});
}
var slideIndex = 0;
// showSlides();
function showSlides() {
removeActive();
slideIndex++;
if (slideIndex > slideCount) {
slideIndex = 1
}
slides[slideIndex - 1].classList.add('active');
paginationBullets[slideIndex - 1].classList.add('active');
setTimeout(showSlides, 2000);
}
.myMain {
display: flex;
flex-direction: column;
}
/* slider */
.slide {
position: absolute;
opacity: 0;
transition: opacity 1s;
z-index: var(--z-normal);
width: 100%;
text-align: center;
height: 40rem;
color: #fff;
}
.sliderContainer .active {
opacity: 1;
}
.sliderControls .indicators ul {
position: absolute;
z-index: 2;
text-align: center;
top: 35rem;
left: 13rem;
display: flex;
}
.sliderControls .indicators ul li {
margin-right: var(--mg-3);
background-color: var(--light-color);
/* color: var(--light-color); */
width: 1rem;
height: 1rem;
border-radius: 50%;
cursor: pointer;
}
<main class="myMain">
<!-- slider -->
<section class="sliderSection">
<div class="sliderContainer">
<div class="slide slide1">
<div class="slidecontent">
<h1>START YOUR STARTUP WITH THIS TEMPLATE</h1>
<button type="button" name="button" class="blueButton">Get Started</button>
</div>
</div>
<div class="slide slide2">
<div class="slidecontent">
<h1>START YOUR STARTUP WITH THIS TEMPLATE</h1>
<button type="button" name="button" class="blueButton">Get Started</button>
</div>
</div>
<div class="slide slide3">
<div class="slidecontent">
<h1>START YOUR STARTUP WITH THIS TEMPLATE</h1>
<button type="button" name="button" class="blueButton">Get Started</button>
</div>
</div>
</div>
<div class="sliderControls">
<span id="indicators" class="indicators">
</span>
</div>
</section>
<!-- features -->
<section class="featuresSection">
<div class="featuresHeader">
<h1>Our Awesome Features</h1>
<p>Far far away, behind the word mountains, far from the countries Vokalia and Consonantia, there live the blind texts.</p>
</div>
<div class="">
</div>
</section>
</main>
add this
.sliderContainer {
display: flex;
flex-direction: row;
overflow-x: auto;
}
.slide {
flex-shrink: 0;
}
/* slider */
.sliderContainer {
position: relative;
overflow: hidden;
height: 40rem;
width: 100%;
}
.sliderContainer .slide {
position: absolute;
opacity: 0;
transition: opacity 1s;
z-index: var(--z-normal);
text-align: center;
color: #fff;
height: 100%;
width: 100%;
}
So here's the thing: A project I'm doing for film school involves making a website. I am in absolutely no way supposed to be a professional (or even a good) programmer (in fact I'm pretty bad), but I wanted to make an old school 90s/2000s styled website.
I modified some code for modal boxes from https://www.w3schools.com/howto/howto_css_modals.asp and it worked out fine until I needed more modal boxes, because now, when I open the modal boxes, the one which is written first in the code shows up with the backdrop and everything, but the clickable image buttons for the subsequent modal boxes show up on top of the box and its backdrop. I'm not sure what's going on. I tried putting all the code in a single <script> tag and all the css in one <style> tag too, but it did nothing. I think I just don't know what I'm doing.
Sorry for the variable, id and class names being in Portuguese, I am Brazilian and this is for Brazilian college.
PS.: I realize there are like a trillion other huge HTML, CSS and JS sins in my code (such as all CSS and JSS being inline), so it's understandable if you cringe or puke instantly by looking at my code. This is because I hadn't coded in years and didn't have time to relearn the real logic behind everything, and also I am using a terrible sitebuilder which barely lets me use HTML, so I had to trick the site by writing all the code inside an HTML box widget. I think you have to pay for premium to actually use different CSS and JS files. So this is all workarounds on top of workarounds on top of workarounds.
<html>
<head>
</head>
<body bgcolor="#FF6842">
<style>
.container {
position: fixed;
top:150px;
}
.container2 {
position:relative;
right:20px;
}
.container3 {
position:relative;
}
#intro-j {
position:fixed;
top:196px;
left:44px;
color:#ffff00;
}
#balao {
position:fixed;
top:370px;
left:966px;
}
#bem-vindo {
position:fixed;
top:100px;
left:423px;
}
#logoblog {
position:fixed;
top:-2px;
left:51px;
}
#gaiola {
position:fixed;
top:450px;
left:330px;
}
#lona {
position:fixed;
left:248px;
top:15px;
}
#counter {
position:fixed;
top:540px;
left:170px;
}
#janela {
position:fixed;
top:170px;
left:15px;
}
#circo-gif-j {
position:fixed;
top:370px;
left:47px;
}
#menu {
position:fixed;
top:550px;
left:44px;
color:#00ff00;
}
#lc {
color:#00ff00;
}
#mesabolo {
position:fixed;
top:540px;
left:960px;
}
#bolo {
position:fixed;
top:470px;
left:1018px;
}
#computador {
position:fixed;
top:394px;
left:700px;
}
</style>
<div class="container">
<img src="https://i.imgur.com/0uGRDgL.png" alt="Cortinas" height="600px" width="1250px" id="bg">
<div id="mesabolo" class="container" class="container2" class="container3">
<img src="https://i.imgur.com/MKP2Ezx.png" height="170px">
<div id="janela" class="container" class="container2" class="container3">
<img src="https://i.imgur.com/TEFvChC.png">
<div id="intro-j" class="container">text</div>
<div id="circo-gif-j" class="container">
<img src="https://www.gif.ovh/portuguese-gif/Palha%C3%A7o%20Gif/Palha%C3%A7o%20Gif%20(21).gif">
</div>
<div id="menu" class="container"><b>• Cartas<br>• Contato</b></div>
</div>
<div id="lona" class="container" class="container2">
<img src="https://i.imgur.com/ZHX8oEe.png" height="700px">
<div id="counter" class="container" class="container2" class="container3">
<img src="https://i.imgur.com/pGkiIuH.png" height="200px" width="850px">
<div id="bem-vindo" class="container">
<img src="https://gifimage.net/wp-content/uploads/2018/05/seja-bem-vindo-gif-6.gif">
<div id="balao" class="container">
<img src="https://i.imgur.com/pcJDYM7.gif" height="90px">
</div>
<div id="logoblog" class="container">
<img src="https://i.imgur.com/CLC5YzA.gif">
<!--GAIOLA-->
<div id="gaiola" class="container">
<img src="https://i.imgur.com/zlmgazC.gif">
<style>
/* The Modal (background) */
.modal {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}
/* Modal Content */
.modal-content {
position: fixed;
background-color: #ffe38a;
height: 310px;
margin:auto;
left:210px;
top:190px;
}
.modal-body {padding: 2px 16px;}
#modal-text {
color:#c83434;
}
</style>
<div id="myModal" class="modal">
<!-- Modal content -->
<div class="modal-content">
<div class="modal-body">
<p id="modal-text">modal text 1</p>
</div>
</div>
</div>
<script>
// Get the modal
var modal = document.getElementById("myModal");
// Get the button that opens the modal
var btn = document.getElementById("gaiola");
// When the user clicks the button, open the modal
btn.onclick = function() {
modal.style.display = "block";
}
// When the user clicks anywhere outside of the modal, close it
window.addEventListener('click', function(event) {
if (event.target == modal) {
modal.style.display = "none";
modal2.style.display = "none";
}
});
</script>
</div>
<!--BOLO-->
<div id="bolo" class="container">
<img src="https://i.imgur.com/RjoYsYb.gif" height="90px">
<style>
/* The Modal (background) */
.modal2 {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}
/* Modal Content */
.modal-content2 {
position: fixed;
background-color: #ffe38a;
height: 350px;
margin:auto;
left:210px;
top:190px;
}
.modal-body2 {padding: 2px 16px;}
#modal-text2 {
color:#c83434;
}
</style>
<div id="myModal2" class="modal2">
<!-- Modal content -->
<div class="modal-content2">
<div class="modal-body2">
<p id="modal-text2">modal text 2<br></p>
</div>
</div>
</div>
<script>
// Get the modal
var modal2 = document.getElementById("myModal2");
// Get the button that opens the modal
var btn2 = document.getElementById("bolo");
// When the user clicks the button, open the modal
btn2.onclick = function() {
modal2.style.display = "block";
}
// When the user clicks anywhere outside of the modal, close it
window.addEventListener('click', function(event) {
if (event.target == modal2) {
modal2.style.display = "none";
modal.style.display = "none";
}
});
</script>
</div>
<!--COMPUTADOR-->
<div id="computador" class="container">
<img src="https://i.imgur.com/s4sHQ1V.gif" height="200px">
<style>
/* The Modal (background) */
.modal3 {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}
/* Modal Content */
.modal-content3 {
position: fixed;
background-color: #ffe38a;
height: 350px;
margin:auto;
left:210px;
top:190px;
}
.modal-body3 {padding: 2px 16px;}
#modal-text3 {
color:#c83434;
}
</style>
<div id="myModal3" class="modal3">
<!-- Modal content -->
<div class="modal-content3">
<div class="modal-body3">
<p id="modal-text3">modal text 3</p>
</div>
</div>
</div>
<script>
// Get the modal
var modal3 = document.getElementById("myModal3");
// Get the button that opens the modal
var btn3 = document.getElementById("computador");
// When the user clicks the button, open the modal
btn3.onclick = function() {
modal3.style.display = "block";
}
// When the user clicks anywhere outside of the modal, close it
window.addEventListener('click', function(event) {
if (event.target == modal3) {
modal3.style.display = "none";
}
});
</script>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
I am not 100% sure if I understood what you wanted to implement. However, The cause of the problem here might be from the complexity of how everything is in one place which leaves large room for mistakes.
Please try to
Place all your CSS should be placed in the head section if you won't use an external file.
Place your JavaScript properly in the head/before end of the body tag based on what it does. if you won't use an external file.
You don't need to duplicate CSS more than once if the group of elements will share the same style. just use the same class across those elements.
The modal should be pushed down to the bottom of the page to make it easier for your to modify your HTML file.
In cases like this one you should use loops and arrays to minimize the repition of actions (I do understand that you are completely new to it, this is why I am trying to tell you what you can look up.)
I modified your code and applied some changes now all you need to do if you will add a new modal is add a new line to the Array with both the modal's id and its container's id.
Your full page code be found at the bottom of my answer, the following is a snippet for you to preview the code. if this not what you needed can you please explain further maybe I can help?
//Array with a list of the modal id and conatiner id
var modalsArray = [
["modal1", "gaiola"],
["modal2", "bolo"],
["modal3", "computador"],
];
//stores the currently visible modal
var visibleModal;
// When the user clicks anywhere outside of the modal, close it
window.addEventListener("click", function(e) {
if (e.target == visibleModal) {
visibleModal.classList.remove("visible");
visibleModal = "";
document.getElementById('overlay').style.display = 'none';
}
});
//Iterate through the modalsArray and add a click event listener
for (let modal = 0; modal < modalsArray.length; modal++) {
document
.getElementById(modalsArray[modal][1])
.addEventListener("click", function(e) {
for (let mod = 0; mod < modalsArray.length; mod++) {
if (
e.target.offsetParent ==
document.getElementById(modalsArray[mod][1])
) {
//add the visible class to show the modal
document
.getElementById(modalsArray[mod][0])
.classList.add("visible");
//store the currently visible modal in the visible modal variable
visibleModal = document.getElementById(modalsArray[mod][0]);
// stops the click event from propagating up which would hide the modal again
document.getElementById('overlay').style.display = 'block';
e.stopPropagation();
}
}
});
}
.container {
position: fixed;
top: 150px;
}
.container2 {
position: relative;
right: 20px;
}
.container3 {
position: relative;
}
#intro-j {
position: fixed;
top: 196px;
left: 44px;
color: #ffff00;
}
#balao {
position: fixed;
top: 370px;
left: 966px;
}
#bem-vindo {
position: fixed;
top: 100px;
left: 423px;
}
#logoblog {
position: fixed;
top: -2px;
left: 51px;
}
#gaiola {
position: fixed;
top: 450px;
left: 330px;
}
#lona {
position: fixed;
left: 248px;
top: 15px;
}
#counter {
position: fixed;
top: 540px;
left: 170px;
}
#janela {
position: fixed;
top: 170px;
left: 15px;
}
#circo-gif-j {
position: fixed;
top: 370px;
left: 47px;
}
#menu {
position: fixed;
top: 550px;
left: 44px;
color: #00ff00;
}
#lc {
color: #00ff00;
}
#mesabolo {
position: fixed;
top: 540px;
left: 960px;
}
#bolo {
position: fixed;
top: 470px;
left: 1018px;
}
#computador {
position: fixed;
top: 394px;
left: 700px;
}
/* The Modal (background) */
.modal {
display: none;
/* Hidden by default */
position: fixed;
/* Stay in place */
z-index: 1;
/* Sit on top */
left: 0;
top: 0;
width: 100%;
/* Full width */
height: 100%;
/* Full height */
overflow: auto;
/* Enable scroll if needed */
background-color: rgb(0, 0, 0);
/* Fallback color */
background-color: rgba(0, 0, 0, 0.4);
/* Black w/ opacity */
}
/* Modal Content */
.modal-content {
position: fixed;
background-color: #ffe38a;
height: 50%;
width: 50%;
margin: auto;
left: 25%;
top: 25%;
}
.modal-body {
padding: 2px 16px;
}
#modal-text {
color: #c83434;
}
.visible {
display: block !important;
z-index: 3;
}
#overlay {
position: fixed;
/* Sit on top of the page content */
display: none;
/* Hidden by default */
width: 100%;
/* Full width (cover the whole page) */
height: 100%;
/* Full height (cover the whole page) */
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.7);
/* Black background with opacity */
z-index: 2;
/* Specify a stack order in case you're using a different order for other elements */
cursor: pointer;
/* Add a pointer on hover */
}
<body bgcolor="#FF6842">
<div class="container">
<img src="https://i.imgur.com/0uGRDgL.png" alt="Cortinas" height="600px" width="1250px" id="bg" />
<div id="mesabolo" class="container" class="container2" class="container3">
<img src="https://i.imgur.com/MKP2Ezx.png" height="170px" />
<div id="janela" class="container" class="container2" class="container3">
<img src="https://i.imgur.com/TEFvChC.png" />
<div id="intro-j" class="container">text</div>
<div id="circo-gif-j" class="container">
<img src="https://www.gif.ovh/portuguese-gif/Palha%C3%A7o%20Gif/Palha%C3%A7o%20Gif%20(21).gif" />
</div>
<div id="menu" class="container">
<b>• Cartas<br />• Contato</b>
</div>
</div>
<div id="lona" class="container" class="container2">
<img src="https://i.imgur.com/ZHX8oEe.png" height="700px" />
<div id="counter" class="container" class="container2" class="container3">
<img src="https://i.imgur.com/pGkiIuH.png" height="200px" width="850px" />
<div id="bem-vindo" class="container">
<img src="https://gifimage.net/wp-content/uploads/2018/05/seja-bem-vindo-gif-6.gif" />
<div id="balao" class="container">
<img src="https://i.imgur.com/pcJDYM7.gif" height="90px" />
</div>
<div id="logoblog" class="container">
<img src="https://i.imgur.com/CLC5YzA.gif" />
<!--GAIOLA-->
<div id="gaiola" class="container">
<img src="https://i.imgur.com/zlmgazC.gif" />
</div>
<!--BOLO-->
<div id="bolo" class="container">
<img src="https://i.imgur.com/RjoYsYb.gif" height="90px" />
</div>
<!--COMPUTADOR-->
<div id="computador" class="container">
<img src="https://i.imgur.com/s4sHQ1V.gif" height="200px" />
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Modal 1 - GAIOLA-->
<div id="modal1" class="modal">
<!-- Modal content -->
<div class="modal-content">
<div class="modal-body">
<p id="modal-text">modal text 1</p>
</div>
</div>
</div>
<!-- Modal 2 - Computador-->
<div id="modal2" class="modal">
<!-- Modal content -->
<div class="modal-content">
<div class="modal-body">
<p id="modal-text">modal text 2</p>
</div>
</div>
</div>
<!-- Modal 3 - Computador-->
<div id="modal3" class="modal">
<!-- Modal content -->
<div class="modal-content">
<div class="modal-body">
<p id="modal-text">modal text 3</p>
</div>
</div>
</div>
<div id="overlay"></div>
<html>
<head>
<style>
.container {
position: fixed;
top: 150px;
}
.container2 {
position: relative;
right: 20px;
}
.container3 {
position: relative;
}
#intro-j {
position: fixed;
top: 196px;
left: 44px;
color: #ffff00;
}
#balao {
position: fixed;
top: 370px;
left: 966px;
}
#bem-vindo {
position: fixed;
top: 100px;
left: 423px;
}
#logoblog {
position: fixed;
top: -2px;
left: 51px;
}
#gaiola {
position: fixed;
top: 450px;
left: 330px;
}
#lona {
position: fixed;
left: 248px;
top: 15px;
}
#counter {
position: fixed;
top: 540px;
left: 170px;
}
#janela {
position: fixed;
top: 170px;
left: 15px;
}
#circo-gif-j {
position: fixed;
top: 370px;
left: 47px;
}
#menu {
position: fixed;
top: 550px;
left: 44px;
color: #00ff00;
}
#lc {
color: #00ff00;
}
#mesabolo {
position: fixed;
top: 540px;
left: 960px;
}
#bolo {
position: fixed;
top: 470px;
left: 1018px;
}
#computador {
position: fixed;
top: 394px;
left: 700px;
}
/* The Modal (background) */
.modal {
display: none;
/* Hidden by default */
position: fixed;
/* Stay in place */
z-index: 1;
/* Sit on top */
left: 0;
top: 0;
width: 100%;
/* Full width */
height: 100%;
/* Full height */
overflow: auto;
/* Enable scroll if needed */
background-color: rgb(0, 0, 0);
/* Fallback color */
background-color: rgba(0, 0, 0, 0.4);
/* Black w/ opacity */
}
/* Modal Content */
.modal-content {
position: fixed;
background-color: #ffe38a;
height: 50%;
width: 50%;
margin: auto;
left: 25%;
top: 25%;
}
.modal-body {
padding: 2px 16px;
}
#modal-text {
color: #c83434;
}
.visible {
display: block !important;
z-index: 3;
}
#overlay {
position: fixed;
/* Sit on top of the page content */
display: none;
/* Hidden by default */
width: 100%;
/* Full width (cover the whole page) */
height: 100%;
/* Full height (cover the whole page) */
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.7);
/* Black background with opacity */
z-index: 2;
/* Specify a stack order in case you're using a different order for other elements */
cursor: pointer;
/* Add a pointer on hover */
}
</style>
</head>
<body bgcolor="#FF6842">
<div class="container">
<img src="https://i.imgur.com/0uGRDgL.png" alt="Cortinas" height="600px" width="1250px" id="bg" />
<div id="mesabolo" class="container" class="container2" class="container3">
<img src="https://i.imgur.com/MKP2Ezx.png" height="170px" />
<div id="janela" class="container" class="container2" class="container3">
<img src="https://i.imgur.com/TEFvChC.png" />
<div id="intro-j" class="container">text</div>
<div id="circo-gif-j" class="container">
<img src="https://www.gif.ovh/portuguese-gif/Palha%C3%A7o%20Gif/Palha%C3%A7o%20Gif%20(21).gif" />
</div>
<div id="menu" class="container">
<b>• Cartas<br />• Contato</b>
</div>
</div>
<div id="lona" class="container" class="container2">
<img src="https://i.imgur.com/ZHX8oEe.png" height="700px" />
<div id="counter" class="container" class="container2" class="container3">
<img src="https://i.imgur.com/pGkiIuH.png" height="200px" width="850px" />
<div id="bem-vindo" class="container">
<img src="https://gifimage.net/wp-content/uploads/2018/05/seja-bem-vindo-gif-6.gif" />
<div id="balao" class="container">
<a href="javascript:alert('---');"><img src="https://i.imgur.com/pcJDYM7.gif"
height="90px" /></a>
</div>
<div id="logoblog" class="container">
<img src="https://i.imgur.com/CLC5YzA.gif" />
<!--GAIOLA-->
<div id="gaiola" class="container">
<img src="https://i.imgur.com/zlmgazC.gif" />
</div>
<!--BOLO-->
<div id="bolo" class="container">
<img src="https://i.imgur.com/RjoYsYb.gif" height="90px" />
</div>
<!--COMPUTADOR-->
<div id="computador" class="container">
<img src="https://i.imgur.com/s4sHQ1V.gif" height="200px" />
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Modal 1 - GAIOLA-->
<div id="modal1" class="modal">
<!-- Modal content -->
<div class="modal-content">
<div class="modal-body">
<p id="modal-text">modal text 1</p>
</div>
</div>
</div>
<!-- Modal 2 - Computador-->
<div id="modal2" class="modal">
<!-- Modal content -->
<div class="modal-content">
<div class="modal-body">
<p id="modal-text">modal text 2</p>
</div>
</div>
</div>
<!-- Modal 3 - Computador-->
<div id="modal3" class="modal">
<!-- Modal content -->
<div class="modal-content">
<div class="modal-body">
<p id="modal-text">modal text 3</p>
</div>
</div>
</div>
<div id="overlay"></div>
<!--Scripts start-->
<script>
//Array with a list of the modal id and conatiner id
var modalsArray = [
["modal1", "gaiola"],
["modal2", "bolo"],
["modal3", "computador"],
];
//stores the currently visible modal
var visibleModal;
// When the user clicks anywhere outside of the modal, close it
window.addEventListener("click", function (e) {
if (e.target == visibleModal) {
visibleModal.classList.remove("visible");
visibleModal = "";
document.getElementById('overlay').style.display = 'none';
}
});
//Iterate through the modalsArray and add a click event listener
for (let modal = 0; modal < modalsArray.length; modal++) {
document
.getElementById(modalsArray[modal][1])
.addEventListener("click", function (e) {
for (let mod = 0; mod < modalsArray.length; mod++) {
if (
e.target.offsetParent ==
document.getElementById(modalsArray[mod][1])
) {
//add the visible class to show the modal
document
.getElementById(modalsArray[mod][0])
.classList.add("visible");
//store the currently visible modal in the visible modal variable
visibleModal = document.getElementById(modalsArray[mod][0]);
// stops the click event from propagating up which would hide the modal again
document.getElementById('overlay').style.display = 'block';
e.stopPropagation();
}
}
});
}
</script>
</body>
</html>