JS-Changing the background image by scrolling - javascript

My Files:
https://jsfiddle.net/claudiopb/f8y4mnc6/2/
I have 2 background images. When the scroll invades the Y coordinate at the top of div 4, I would like to change the body's fullscreen image to the other background image.
As you can see in these examples below:
I started to make a JavaScript to intercept if the scroll coordinate was equal to the top of the div, to do the CSS class change, but it is not working.
HTML
<!DOCTYPE html>
<html lang="pt-BR">
<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">
<link rel="stylesheet" href="css/styles.css">
<script src="js/script.js" defer></script>
<title>Background changing</title>
</head>
<body class="bg-1">
<div class="style-1 item-1">
<h1>Item-1</h1>
</div>
<div class="style-1 item-2">
<h1>Item-2</h1>
</div>
<div class="style-1 item-3">
<h1>Item-3</h1>
</div>
<div class="style-1 item-4">
<h1>Item-4</h1>
<p>Here I want the background image changing!!!</p>
</div>
<div class="style-1 item-5">
<h1>Item-5</h1>
</div>
</body>
</html>
CSS
* {
border: 0;
padding: 0;
margin: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
position:relative;
}
.bg-1 {
background:url('https://cdn.pixabay.com/photo/2016/05/05/02/37/sunset-1373171__480.jpg') no-repeat fixed center bottom;
background-size: cover;
}
.bg-2 {
background: url('https://images.unsplash.com/photo-1434725039720-aaad6dd32dfe?ixlib=rb-1.2.1&w=1080&fit=max&q=80&fm=jpg&crop=entropy&cs=tinysrgb') no-repeat fixed center top;
background-size: cover;
}
.style-1 {
height:800px;
width:600px;
display:flex;
justify-content: center;
align-items: center;
flex-direction: column;
font-size: 30px;
text-align: center;
padding-left: 20px;
padding-right: 20px;
}
.style-1 h1 {
padding-bottom:40px;
}
.item-1 {
background-color:green
}
.item-2 {
background-color:blue
}
.item-3 {
background-color:grey
}
.item-4 {
background-color:orange
}
.item-5 {
background-color:red
}
JS
const el = document.querySelector(".item-4")
const result = getOffset(el)
let scroll = null;
function getOffset(el) {
const rect = el.getBoundingClientRect();
return rect.top
}
window.addEventListener("scroll", (event) => {
scroll = this.scrollY;
console.log(scroll)
if (scroll == result) {
console.log('true')
/**
* if this returns true, write the lines of code to switch the body's class.
*
*/
}
});

Related

Fixing washed-out image transition in a slideshow

I am making a simple slideshow with images fading in and out. The image transition is done in CSS. I am having some issues of washed-out images during the transition. The problem is particularly visible when using the keyboard and keeping a key down. Below is a very basic example (simply press any key to change images).
Is there an easy fix to this? Ideally, I would like to have something similar to that website, which I find much more pleasing to the eye.
I have tried to play with the transition-timing-function and different transition-duration between the image and .visible rules in the CSS, without success.
const imgs = document.querySelectorAll('img');
const imgCount = imgs.length - 1;
let index = 0;
imgs[index].classList.add('visible');
window.addEventListener('keydown', () => {
imgs[index].classList.remove('visible');
index = index === imgCount ? 0 : ++index;
imgs[index].classList.add('visible');
});
* {
box-sizing: border-box;
}
html {
height: 100%;
}
body, figure {
margin: 0;
padding: 0;
}
body {
height: 100%;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.slideshow {
height: 600px;
width: 800px;
max-width: 100%;
display: flex;
align-items: center;
position: relative;
}
img {
width: 100%;
position: absolute;
opacity: 0;
transition: opacity .3s;
z-index: 2;
}
.visible {
transition: opacity .3s;
opacity: 1;
z-index: 3;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
</head>
<body>
<div class="slideshow">
<img src="https://uploads6.wikiart.org/images/david-roberts/jerusalem-from-the-mount-of-olives-1847.jpg!Large.jpg">
<img src="https://uploads8.wikiart.org/images/david-roberts/departure-of-the-israelites-1830.jpg!Large.jpg">
<img src="https://uploads1.wikiart.org/images/david-roberts/church-of-the-holy-sepulchre-jerusalem-1849.jpg!Large.jpg">
<img src="https://uploads5.wikiart.org/00333/images/david-roberts/david-roberts-1796-1864-the-inauguration-of-the-great-exhibition-1-may-1851-rcin-407143-royal.jpg!Large.jpg">
</div>
</body>
</html>
Use a timer with a 100 millisecond delay with each keydown event
Use a control variable whose value is false with each keydown event
and the next image cannot be displayed until it is false and its value
becomes true when the timer time has come.
const imgs = document.querySelectorAll('img');
const imgCount = imgs.length - 1;
let index = 0;
imgs[index].classList.add('visible');
var allow = true;
window.addEventListener('keydown', () => {
if (allow) {
imgs[index].classList.remove('visible');
index = index === imgCount ? 0 : ++index;
imgs[index].classList.add('visible');
allow = false;
displayTimer(200);
}
});
var timer;
function displayTimer(sec) {
var dec = sec - 100;
if (dec == 0) {
window.clearTimeout(timer);
allow = true;
} else {
timer = setTimeout(function() {
displayTimer(dec)
}, 100);
}
}
* {
box-sizing: border-box;
}
html {
height: 100%;
}
body,
figure {
margin: 0;
padding: 0;
}
body {
height: 100%;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.slideshow {
height: 600px;
width: 800px;
max-width: 100%;
display: flex;
align-items: center;
position: relative;
}
img {
width: 100%;
position: absolute;
opacity: 0;
transition: opacity .3s;
z-index: 2;
}
.visible {
transition: opacity .3s;
opacity: 1;
z-index: 3;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
</head>
<body>
<div class="slideshow">
<img src="https://uploads6.wikiart.org/images/david-roberts/jerusalem-from-the-mount-of-olives-1847.jpg!Large.jpg">
<img src="https://uploads8.wikiart.org/images/david-roberts/departure-of-the-israelites-1830.jpg!Large.jpg">
<img src="https://uploads1.wikiart.org/images/david-roberts/church-of-the-holy-sepulchre-jerusalem-1849.jpg!Large.jpg">
<img src="https://uploads5.wikiart.org/00333/images/david-roberts/david-roberts-1796-1864-the-inauguration-of-the-great-exhibition-1-may-1851-rcin-407143-royal.jpg!Large.jpg">
</div>
</body>
</html>

Add transition when switching img src

I'm adding a feature to a squarespace website. The feature is a new image fade-in/fade-out effect when the mouse is hovering over one of three buttons. The problem is that the static/main image is an img element in the html and not in the css, so I can't change it like that. I have tried to change the element.src in javascript however there's no transition. Is the best way to add another element in the javascript code so I can make the added img transition with opacity? That just seems like a lot of extra work trying to put it in when working in squarespace.
Any suggestions? By the way I have a snippet showing my code and the issue.
PS, the buttons are under the image at the moment. That doesn't need a fix.
let jw_backgroundswitch = document.querySelector('.section-background img');
let jw_btn = document.querySelectorAll('.sqs-block-content h1 a');
let images = ['https://static1.squarespace.com/static/5fe99a39cc46cf62c078c5a0/t/5ff85ea72dbf216159f9567d/1610112687144/homepage_story_1500x896.jpg', 'https://static1.squarespace.com/static/5fe99a39cc46cf62c078c5a0/t/5ff85e88b1f66202d7f3e8e4/1610112659325/homepage_art_1500x896.jpg', 'https://static1.squarespace.com/static/5fe99a39cc46cf62c078c5a0/t/5ff85ebf1701e075bcb4c460/1610112707995/homepage_Studio_1500x896.jpg'];
jw_btn.forEach(function(jw_btn_current, index) {
jw_btn_current.addEventListener('mouseenter', function() {
jw_backgroundswitch.src = images[index];
});
jw_btn_current.addEventListener('mouseleave', function() {
jw_backgroundswitch.src = 'https://static1.squarespace.com/static/5fe99a39cc46cf62c078c5a0/t/5ff44194b93643179814a20d/1610108761001/Lady+in+blue.jpg';
});
});
*,*::before,*::after {
box-sizing: border-box;
padding: 0;
margin: 0;
}
body{
height: 200vh;
}
.section-background{
}
img{
background-repeat: no-repeat;
transition: all .5s ease-in-out;
}
.ulwrapper{
display: flex;
height: 100vh;
align-items: center;
}
.sqs-block-content{
display: flex;
width: 100%;
height: 4rem;
list-style: none;
}
h1{
margin: auto;
cursor: pointer;
}
h1 a{
font-weight: bolder;
text-decoration: none;
color: black;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class='section-background'>
<img alt="" data-src="https://static1.squarespace.com/static/5fe99a39cc46cf62c078c5a0/t/5ff44194b93643179814a20d/1610108761001/Lady+in+blue.jpg" data-image="https://static1.squarespace.com/static/5fe99a39cc46cf62c078c5a0/t/5ff44194b93643179814a20d/1610108761001/Lady+in+blue.jpg" data-image-dimensions="2000x1195" data-image-focal-point="0.24133662454825583,0.20697233746829613" data-load="false" data-parent-ratio="1.4" style="width: 100%; height: 100%; object-position: 0% 20.6972%; object-fit: cover;" class="" data-image-resolution="2500w" src="https://static1.squarespace.com/static/5fe99a39cc46cf62c078c5a0/t/5ff44194b93643179814a20d/1610108761001/Lady+in+blue.jpg?format=2500w">
<div class="ulwrapper">
<div class="sqs-block-content">
<h1 class="jw_btn"><a>Button1</a></h1>
<h1 class="jw_btn"><a>Button2</a></h1>
<h1 class="jw_btn"><a>Button3</a></h1>
</div>
</div>
</div>
<script src="app.js"></script>
</body>
</html>
I would superpose two <img> elements inside a <div> wrapper and play with the opacity. The static picture will be above when the mouse is not hovering on a button and when hovering, first you set the image below with imageBelow.src = images[i] and then change the opacity of the image above with imageAbove.style.opacity = "0";
wrapImages();
let imageBelow = document.querySelector('.pics .below');
let imageAbove = document.querySelector('.pics .above');
let jw_btn = document.querySelectorAll('.sqs-block-content h1 a');
let images = ['https://static1.squarespace.com/static/5fe99a39cc46cf62c078c5a0/t/5ff85ea72dbf216159f9567d/1610112687144/homepage_story_1500x896.jpg', 'https://static1.squarespace.com/static/5fe99a39cc46cf62c078c5a0/t/5ff85e88b1f66202d7f3e8e4/1610112659325/homepage_art_1500x896.jpg', 'https://static1.squarespace.com/static/5fe99a39cc46cf62c078c5a0/t/5ff85ebf1701e075bcb4c460/1610112707995/homepage_Studio_1500x896.jpg'];
jw_btn.forEach(function(jw_btn_current, index) {
jw_btn_current.addEventListener('mouseenter', function() {
imageBelow.src = images[index];
imageAbove.style.opacity = "0";
});
jw_btn_current.addEventListener('mouseleave', function() {
imageAbove.src = 'https://static1.squarespace.com/static/5fe99a39cc46cf62c078c5a0/t/5ff44194b93643179814a20d/1610108761001/Lady+in+blue.jpg';
imageAbove.style.opacity = "1";
});
});
function wrapImages() {
let sectionBackground = document.querySelector('.section-background');
let images = sectionBackground.getElementsByTagName('img');
var newDiv = document.createElement("div");
newDiv.className="pics";
sectionBackground.insertBefore(newDiv, sectionBackground.firstChild);
newDiv.appendChild(images[0]);
newDiv.appendChild(images[1]);
images[0].className="below";
images[1].className="above";
}
*,*::before,*::after {
box-sizing: border-box;
padding: 0;
margin: 0;
}
body{
height: 200vh;
}
img{
background-repeat: no-repeat;
transition: all .5s ease-in-out;
}
.pics {
position: relative;
width: 100%;
height: 100vh;
}
.pics > img {
position: absolute;
transition: all .4s ease;
}
.ulwrapper{
display: flex;
height: 100vh;
align-items: center;
}
.sqs-block-content{
display: flex;
width: 100%;
height: 4rem;
list-style: none;
}
h1{
margin: auto;
cursor: pointer;
}
h1 a{
font-weight: bolder;
text-decoration: none;
color: black;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class='section-background'>
<img alt=""
data-src="https://static1.squarespace.com/static/5fe99a39cc46cf62c078c5a0/t/5ff44194b93643179814a20d/1610108761001/Lady+in+blue.jpg"
data-image="https://static1.squarespace.com/static/5fe99a39cc46cf62c078c5a0/t/5ff44194b93643179814a20d/1610108761001/Lady+in+blue.jpg"
data-image-dimensions="2000x1195" data-image-focal-point="0.24133662454825583,0.20697233746829613"
data-load="false" data-parent-ratio="1.4"
style="width: 100%; height: 100%; object-position: 0% 20.6972%; object-fit: cover;"
data-image-resolution="2500w"
src="https://images.unsplash.com/photo-1610043238036-7309f1cc52d8?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1534&q=80">
<img alt=""
data-src="https://static1.squarespace.com/static/5fe99a39cc46cf62c078c5a0/t/5ff44194b93643179814a20d/1610108761001/Lady+in+blue.jpg"
data-image="https://static1.squarespace.com/static/5fe99a39cc46cf62c078c5a0/t/5ff44194b93643179814a20d/1610108761001/Lady+in+blue.jpg"
data-image-dimensions="2000x1195" data-image-focal-point="0.24133662454825583,0.20697233746829613"
data-load="false" data-parent-ratio="1.4"
style="width: 100%; height: 100%; object-position: 0% 20.6972%; object-fit: cover;"
data-image-resolution="2500w"
src="https://static1.squarespace.com/static/5fe99a39cc46cf62c078c5a0/t/5ff44194b93643179814a20d/1610108761001/Lady+in+blue.jpg?format=2500w">
</div>
<div class="ulwrapper">
<div class="sqs-block-content">
<h1 class="jw_btn"><a>Button1</a></h1>
<h1 class="jw_btn"><a>Button2</a></h1>
<h1 class="jw_btn"><a>Button3</a></h1>
</div>
</div>
</div>
<script src="app.js"></script>
</body>
</html>
EDIT
If as you stated SquareSpace doesn´t allow you to add a wrapper to the HTML, then you can add a wrapper programatically. I have now added the function wrapImages() which must be called at the beginning of the JS code.

Responsive Carrousel in JavaScript

how are you, well I am triying to make a Carrousel responsive with Javascritp, but I am struggling with the logic here.
I've tried everything, with css is imposible, because the images are note background images. I am about to go crazy with this.
This is the code
var carruselimagenes = []
carruselimagenes [0] = ["articulos.html" , "imagenes/cover1.png"]
carruselimagenes [1] = ["contacto.html" , "imagenes/cover2.png"]
carruselimagenes [2] = ["contacto.html" , "imagenes/cover3.png", "imagenes/cover400.png"]
carruselimagenes [3] = ["jardinvertical.html" , "imagenes/cover4.png"]
var carruselresponsive = []
carruselresponsive [0] = ["imagenes/cover400.png"]
var links = document.getElementById('linkcarrusel')
var imagenes = document.getElementById('imagencarrusel')
links.href = carruselimagenes [0][0]
imagenes.src= carruselimagenes [0][1]
var imagenesResponsive = responsive window.matchMedia("(max-width: 599px)")
if (window.matchMedia("(max-width: 599px)").matches) { imagenes.src = carruselresponsive [0]
else {
imagenes.src = carruselimagenes [0][1]
}
}
var orden = 0
function carruselautomatico() {
orden++
if (orden>3) {orden=0}
links.href = carruselimagenes[orden][0]
imagenes.src = carruselimagenes[orden][1]
}
setInterval(carruselautomatico, 6000)
function carruselflechasadelante() {
orden++
if (orden>3) {orden=0}
links.href = carruselimagenes[orden][0]
imagenes.src = carruselimagenes[orden][1]
}
function carruselflechasatras() {
orden--
if (orden<0) {orden=3}
links.href = carruselimagenes[orden][0]
imagenes.src = carruselimagenes[orden][1]
}
body{background-color: white;
font-family: 'Open Sans', sans-serif;}
header, section, footer{ width: 960px;
margin-right: auto;
margin-left: auto;
}
#carrusel{ width:960px;
height: 350px;
background-color: #d4d9a0;
margin-top: 15px;
margin-bottom: 15px;
position: relative;
text-align: center;
}
button{ background-color: none;
height: 30px;
width: 90px;
margin-top: 10px;
margin-left: 35px;
border-color: #00ab84;
color: #00ab84;
display:inline-block;
font-size: 30px;
text-align: center;
line-height: 5px;
}
button:hover{background-color: #00ab84;
color:white;
transition: 1s;}
/** Responsive**/
#media all and (min-width: 600px) and (max-width: 1023px){
#carrusel{ width:400px;
height: 400px;}
}
/*Fin responsive 600 1023**/
#media all and (max-width: 599px) {
#carrusel{ width:300px;
height: 400px;
}
}
<!DOCTYPE html>
<html>
<head>
<title>Prueba Carrusell</title>
<link rel="stylesheet" type="text/css" href="css/stylecarrusel.css">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1" >
<script type="text/javascript" src="js/script.js"></script>
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Open+Sans&display=swap" rel="stylesheet">
</head>
</head>
<body>
<div id="carrusel">
<img src="" id="imagencarrusel">
<button id="atras" onclick="carruselflechasatras()"><</button>
<button id="adelante" onclick="carruselflechasadelante()">></button>
</div>
<script type="text/javascript" src="js/scriptcarrusel.js"></script>
</body>
</html>
It just doesn't work, and my head is about to explode. Could somebody give me a hand??
Best!
Matt
I think the reason your having trouble is because the image shows at the full size no matter what the container size is.
you can stop it using css overflow: hidden; but for you try this:
#carrusel img {
max-width: 100%;
}

How to make my spacer work in the fixed header?

I created a simple header. There are two boxes (DIVs) to be more precise. Both of them are part of the header
HEADER
BOX 1
BOX 2
I want the first box to dissapear as the user scrolls down but keep the second box fixed. The second box which is fixed also shrinks a little bit in height.
The problem is that I want the "Content" heading to be visible right in the moment when the second box shrinks and becomes fixed. However as the user scrolls down more I want the "Content" header to dissapear below the fixed header with the other content as well.
I wanted to solve this using vanilla JavaScript. I suppose the solution for my issue is just a spacer, but I added it and doesn't seem to work.
"use strict";
const header = document.querySelector(".header-main");
const sticky = header.offsetTop;
window.addEventListener("scroll", event => {
if (window.pageYOffset > sticky) {
header.classList.add("is-sticky");
header.style.height = "70px";
} else {
header.classList.remove("is-sticky");
header.style.height = "100px";
}
});
:root {
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
body {
margin: 0;
padding: 0;
}
p {
margin: 0;
}
.header-above {
background: lightseagreen;
color: #fff;
height: 100px;
}
.header-main {
background: #0A246A;
color: #fff;
height: 100px;
transition: all 0.2s linear;
}
.header-main.is-sticky {
position: fixed;
top: 0;
width: 100%;
}
.header-main.is-sticky + .main {
padding-top: 120px;
}
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="fixed-header-plusabove.css">
<title>Fixed Header Plus Above</title>
</head>
<body>
<header class="header">
<div class="header-above">
<div class="header-above-container">
<p>Header Above Container</p>
</div>
</div>
<div class="header-main">
<div class="header-main-container">
<p>Header main</p>
</div>
</div>
</header>
<main>
<h1>Content</h1>
<script>
for (let i = 0; i < 100; i++) {
document.write("<p>Some text...</p>");
}
</script>
</main>
<script src="fixed-header-plusabove.js"></script>
</body>
</html>
I think the spacing idea, could be a solution for you.
You have 2 mistakes in your shown code:
.header-main.is-sticky + .main
there is no class named main, only the html tag <main>
with the code line above, even with <main>, you won't affect the main element.
If you add a class like .is-sticky to the parent class header.header you could use ur code line like this:
header.header.is-sticky + main
"use strict";
const parentHeader = document.querySelector(".header");
const header = document.querySelector(".header-main");
const sticky = header.offsetTop;
window.addEventListener("scroll", event => {
if (window.pageYOffset > sticky) {
header.classList.add("is-sticky");
parentHeader.classList.add("is-sticky");
header.style.height = "70px";
} else {
header.classList.remove("is-sticky");
parentHeader.classList.remove("is-sticky");
header.style.height = "100px";
}
});
:root {
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
body {
margin: 0;
padding: 0;
}
p {
margin: 0;
}
.header-above {
background: lightseagreen;
color: #fff;
height: 100px;
}
.header-main {
background: #0A246A;
color: #fff;
height: 100px;
transition: all 0.2s linear;
}
.header-main.is-sticky {
position: fixed;
top: 0;
width: 100%;
}
header.header.is-sticky + main {
padding-top: 120px;
}
<header class="header">
<div class="header-above">
<div class="header-above-container">
<p>Header Above Container</p>
</div>
</div>
<div class="header-main">
<div class="header-main-container">
<p>Header main</p>
</div>
</div>
</header>
<main>
<h1>Content</h1>
<script>
for (let i = 0; i < 100; i++) {
document.write("<p>Some text...</p>");
}
</script>
</main>
<script src="fixed-header-plusabove.js"></script>

How to automatically extend parent height when the total height of children overflows?

The function I want to implement is that a parent element that contains an indefinite number of child elements can automatically extend its height to the furthest point of the children when the total height of the children exceeds the parent's. The parent has a fixed height if the children's total height do not exceed that height. Here's the diagram:
I've tried and searched for hours and still couldn't get it to work. Don't know what's been missing here. Here's a demo snippet and when you click on the blue panel it will exceed the white panel but the white one does not extend accordingly.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
<style>
html,
body {
height: 100%;
background-color: grey;
margin: 0;
}
#left-panel {
position: relative;
width: 256px;
height: 100%;
background-color: white;
}
#child-panel {
position: absolute;
width: 30%;
height: 40%;
top: 20%;
left: 30%;
background-color: blue;
}
</style>
<script>
window.onload = init;
function init() {
var leftPanel = document.getElementById("left-panel");
var childPanel = document.getElementById("child-panel");
childPanel.onclick = function(ev) {
if (childPanel.offsetHeight < leftPanel.offsetHeight) {
childPanel.style.height = leftPanel.offsetHeight + 100 + "px";
leftPanel.style.height = leftPanel.offsetHeight + 100 + "px";
} else {
childPanel.style.height = "40%";
leftPanel.style.height = "100%";
}
}
}
</script>
</head>
<body>
<div id="left-panel">
<div id="child-panel"></div>
</div>
</body>
</html>
it is simple, you don't need javascript to get the right bhavior
first i used this html and css code that gives the same ui as yours in the pictures :
<div class="parent-purpel">
<div class="firstChild-yellow">
<div class="thirdChild-orange">
</div>
</div>
it gives me the result below :
then i used flex in the css :
.firstChild-yellow{
background-color: yellow;
width: 30%;
height: auto;
margin : 30px;
display: flex; /* <====================== */
flex-direction: column; /* <======= to get orange squares in vertical align */}
important ! :
we have to use an auto height in the yellow and the purpel divs :
.parent-purpel{
background-color: purple;
width: 100%;
height: auto; /*<===== important*/ }
.firstChild-yellow{
background-color: yellow;
width: 30%;
height: auto; /*<===== important*/
margin : 30px;
display: flex;
flex-direction: column;}
Now even we add orange elements to the yellow div we will have variable height of the divs yellow and purpel like that :
i hope that will help you thanks !
here is the full code :
html : test1.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="test1.css">
<title>Document</title>
</head>
<body>
<div class="parent-purpel">
<div class="firstChild-yellow">
<div class="thirdChild-orange">
</div>
<div class="thirdChild-orange">
</div>
<div class="thirdChild-orange">
</div>
<div class="thirdChild-orange">
</div>
</div>
</div>
</body>
</html>
CSS : test1.css
.parent-purpel{
background-color: purple;
width: 100%;
height: auto;}
.firstChild-yellow{
background-color: yellow;
width: 30%;
height: auto;
margin : 30px;
display: flex;
flex-direction: column;}
.thirdChild-orange{
background-color: orange;
width: 60%;
height: 200px;
margin: 30px;}
Try this one:
var childTop = childPanel.offsetTop
if (childPanel.offsetHeight < leftPanel.offsetHeight) {
childPanel.style.height = leftPanel.offsetHeight - childTop + "px";
leftPanel.style.height = leftPanel.offsetHeight + "px";
}
you were setting child height (cHeight) as parent height (pHeight) so let's assume
pHeight = 100px;
cheight = pHeight in your case childPanel.style.height = leftPanel.offsetHeight
it means both elements are having the same height but child element also have top: 20%; that you have to reduce from the height of the child.
Calculate Top of the child: var childTop = childPanel.offsetTop
and then reduce from height
childPanel.style.height = leftPanel.offsetHeight - childTop + "px";
Why don't you just try something like;
<!-- min height will be the height that you want to keep fixed if lesser number of children -->
<div style="border:1px solid black; padding:5px; min-height:50px">
<div>
Child 1
</div>
<div>
Child 2
</div>
<div>
Child 3
</div>
<div>
Child 4
</div>
</div>
it's the:
#child-panel {
position: absolute;
}
that is causing the behaviour, to get the position use padding and margin:
#left-panel {
padding: 5% 2%;
}
#child-panel {
margin: auto;
}
The key is to use
min-height: 100%;
height: auto;
for parent panel and don't use
position: absolute;
for the child panels. If you want to re-position the child panels use a wrapper panel instead. Here's the code that when you click on the blue panels the parent and the panels are all extended accordingly.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
<style>
html, body {
height: 100%;
background-color: grey;
margin: 0;
}
#left-panel {
width: 256px;
min-height: 100%;
height: auto;
background-color: white;
}
.child-panel-wrapper {
width: 30%;
height: auto;
background-color: yellow;
position: relative;
left: 30%;
}
.child-panel {
background-color: blue;
height: 200px;
}
</style>
<script>
window.onload = init;
function init() {
var childPanels = document.getElementsByClassName("child-panel");
for (var i = 0; i < childPanels.length; i++) {
var panel = childPanels[i];
panel.addEventListener("click", function (evt) {
if (this.offsetHeight <= 200) {
this.style.height = 600 + "px";
} else {
this.style.height = 200 + "px";
}
})
}
}
</script>
</head>
<body>
<div id="left-panel">
<div class="child-panel-wrapper">
<div class="child-panel"></div><br>
<div class="child-panel"></div><br>
<div class="child-panel"></div>
</div>
</div>
</body>
</html>

Categories

Resources