Create slider like infinite scrolling with CSS - javascript

I am trying to create CSS slider infinite scroll, but without appending/adding/creating DOM elements. Infinite scroll as in when the last slide is reached, the first slide should be shown again after it.
I have a fixed width slide, so the use of slick and box slider plugin does not work for me.
.slider-wrap {
white-space: nowrap;
overflow-x: auto;
overflow-y: hidden;
border: 1px solid red;
}
.slider-wrap .slide {
display: inline-block;
width: 200px;
margin: 5px;
}
.slider-wrap .slide img {
width: 100%;
}
<div class="slider-wrap">
<div class="slide">
<img src="http://via.placeholder.com/350x150">
</div>
<div class="slide">
<img src="http://via.placeholder.com/350x150">
</div>
<div class="slide">
<img src="http://via.placeholder.com/350x150">
</div>
<div class="slide">
<img src="http://via.placeholder.com/350x150">
</div>
<div class="slide">
<img src="http://via.placeholder.com/350x150">
</div>
<div class="slide">
<img src="http://via.placeholder.com/350x150">
</div>
<div class="slide">
<img src="http://via.placeholder.com/350x150">
</div>
</div>

Here are two options:
clone the items: you get a more natural approach (cloning isn't that bad). That's the system you would usually find on websites to add more content.
revert the position scroll position to another position to make it seem the slider never ends. Beware this will not make the scroll bar smaller as the content of the slider never gets changed
(a) Cloning
As you said you can clone the images.
The trick is to determine when the scroll has reached the end of the slider to clone more images in:
$(function() {
$('.slider-wrap').scroll(function() {
const slider = $(this);
width = slider.innerWidth()
scrollWidth = slider[0].scrollWidth;
scrollLeft = slider.scrollLeft();
if(scrollWidth - width == scrollLeft) {
slider.children().clone().appendTo(slider);
}
});
});
.slider-wrap {
white-space: nowrap;
overflow-x: auto;
overflow-y: hidden;
border: 1px solid red;
}
.slider-wrap .slide {
display: inline-block;
width: 200px;
margin: 5px;
}
.slider-wrap .slide img {
width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="slider-wrap">
<div class="slide">
<img src="http://via.placeholder.com/350x150">
</div>
<div class="slide">
<img src="http://via.placeholder.com/350x150">
</div>
<div class="slide">
<img src="http://via.placeholder.com/350x150">
</div>
<div class="slide">
<img src="http://via.placeholder.com/350x150">
</div>
<div class="slide">
<img src="http://via.placeholder.com/350x150">
</div>
<div class="slide">
<img src="http://via.placeholder.com/350x150">
</div>
<div class="slide">
<img src="http://via.placeholder.com/350x150">
</div>
</div>
And here's a demo:
$(function(){$('.slider-wrap').scroll(function(){const slider=$(this);var $width=slider.innerWidth()
var $scrollWidth=slider[0].scrollWidth;var $scrollLeft=slider.scrollLeft();if($scrollWidth-$width==$scrollLeft){slider.children().clone().appendTo(slider)}})})
.slider-wrap{white-space:nowrap;overflow-x:auto;overflow-y:hidden;border:1px solid red}.slider-wrap .slide{display:inline-block;margin:5px}.slider-wrap .slide img{height:120px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><div class="slider-wrap"> <div class="slide"> <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTa4e2VF6cfou9oL0cc5OAzVTEbmAgFjIW2r-7lTkpOljG9k38N"> </div><div class="slide"> <img src="https://nbocdn.akamaized.net/Assets/Images_Upload/2018/01/06/0060bbce-f2f2-11e7-bf60-029def90d6d6_web_scale_0.0542636_0.0542636__.jpg?maxheight=460&maxwidth=638&scale=both"> </div><div class="slide"> <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQr0xQ-gVF1Sy1a1sHoUyfGdrBwyz-5u0Tirkt-uNCKd-AzNXY1ww"> </div><div class="slide"> <img src="https://cdn.pixabay.com/photo/2017/05/29/15/34/kitten-2354016_960_720.jpg"> </div><div class="slide"> <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTJLwVbVu6tjubsduR43je-Muk7p8lAKDu569GuL_yDWGzrZwp2"> </div><div class="slide"> <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQRHeW6zNDdDQBwtpuu3RvLW1ihM3Za-OLBoOMRR_4z7GvwYor2eQ"> </div><div class="slide"> <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRKeCmurlUrTtd4CjvXYskGVAUAiDq5X49iNb3XhOcMss2vN8c6"> </div></div>
(b) A hack with scrollLeft
You could also go straight back to the first slide container by setting the scrollLeft to the position when it first added a new slide container:
let firstPos = undefined;
$('.slider').scroll(function() {
const slider = $(this);
width = slider.innerWidth()
scrollWidth = slider[0].scrollWidth;
scrollLeft = slider.scrollLeft();
isEndOfSlider = (scrollWidth - width) == scrollLeft;
numberOfWraps = slider.children().length;
if(isEndOfSlider) {
if(numberOfWraps == 1) {
firstPos = scrollLeft;
slider.children().first().clone().appendTo(slider);
} else {
slider.scrollLeft(firstPos);
}
}
});
.slider {
white-space: nowrap;
overflow-x: auto;
overflow-y: hidden;
border: 1px solid red;
}
.slider-wrap {
display: inline-block;
}
.slider-wrap .slide {
display: inline-block;
width: 200px;
margin: 5px;
}
.slider-wrap .slide img {
width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="slider">
<div class="slider-wrap">
<div class="slide">1
<img src="http://via.placeholder.com/350x150">
</div>
<div class="slide">2
<img src="http://via.placeholder.com/350x150">
</div>
<div class="slide">3
<img src="http://via.placeholder.com/350x150">
</div>
<div class="slide">...
<img src="http://via.placeholder.com/350x150">
</div>
<div class="slide">...
<img src="http://via.placeholder.com/350x150">
</div>
<div class="slide">-2
<img src="http://via.placeholder.com/350x150">
</div>
<div class="slide">-1
<img src="http://via.placeholder.com/350x150">
</div>
</div>
</div>
Here's a demo:
let firstPos=undefined;$('.slider').scroll(function(){const slider=$(this);width=slider.innerWidth()
scrollWidth=slider[0].scrollWidth;scrollLeft=slider.scrollLeft();isEndOfSlider=(scrollWidth-width)==scrollLeft;numberOfWraps=slider.children().length;if(isEndOfSlider){if(numberOfWraps==1){firstPos=scrollLeft;slider.children().first().clone().appendTo(slider)}else{slider.scrollLeft(firstPos)}}})
.slider{white-space:nowrap;overflow-x:auto;overflow-y:hidden;border:1px solid red}.slider-wrap{display:inline-block}.slider-wrap .slide{display:inline-block;margin:5px}.slider-wrap .slide img{width:auto;height:120px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><div class="slider"> <div class="slider-wrap"> <div class="slide"> <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTa4e2VF6cfou9oL0cc5OAzVTEbmAgFjIW2r-7lTkpOljG9k38N"> </div><div class="slide"> <img src="https://nbocdn.akamaized.net/Assets/Images_Upload/2018/01/06/0060bbce-f2f2-11e7-bf60-029def90d6d6_web_scale_0.0542636_0.0542636__.jpg?maxheight=460&maxwidth=638&scale=both"> </div><div class="slide"> <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQr0xQ-gVF1Sy1a1sHoUyfGdrBwyz-5u0Tirkt-uNCKd-AzNXY1ww"> </div><div class="slide"> <img src="https://cdn.pixabay.com/photo/2017/05/29/15/34/kitten-2354016_960_720.jpg"> </div><div class="slide"> <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTJLwVbVu6tjubsduR43je-Muk7p8lAKDu569GuL_yDWGzrZwp2"> </div><div class="slide"> <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQRHeW6zNDdDQBwtpuu3RvLW1ihM3Za-OLBoOMRR_4z7GvwYor2eQ"> </div><div class="slide"> <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRKeCmurlUrTtd4CjvXYskGVAUAiDq5X49iNb3XhOcMss2vN8c6"> </div></div></div>

Related

On scroll down images are moving up

I want on scroll down, that the images are moving up a bit, like on this website:
example site (digital does)
Down the website on digitaldoes you can see what i mean. The images are moving up a bit if you scroll down. Is it maby a lazy-load with images that are fading in or an animation where the images moving for example 5px up?
Here is a: jsfiddle updated!!!
$(document).ready(function () {
$(".img-scroll").css("display", "none");
$(window).scroll(function() {
$( ".img-scroll" ).addClass("animate");
$( ".img-scroll" ).css("display", "block");
console.log("Hey");
});
});
.img-scroll {
-moz-transition: top 10s;
transition: top 10s;
}
.img-scroll.animate {
top: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.1/dist/css/bootstrap.min.css" rel="stylesheet"/>
<div class="row">
<header class="arbeiten">
<h2>{ Logos }</h2>
</header>
</div>
<div id="links">
<div class="row">
<div class="col-xxl-1"></div>
<div class="col-12 col-md-6 col-lg-4 col-xxl-5">
<div class="card shadow-sm first-image">
<a href="https://www.fillmurray.com/1000/1000" title="Test - Logo #1">
<img src="https://www.fillmurray.com/300/150" alt="Test - Logo #1" class="card-img-top logo-hover">
</a>
<div class="card-body">
<p class="card-text">Test - Logo #1</p>
<div class="d-flex justify-content-between align-items-center"></div>
</div>
</div>
</div>
<div class="col-12 col-md-6 col-lg-4 col-xxl-5">
<div class="card shadow-sm">
<a href="https://www.fillmurray.com/1000/1000" title="Test - Logo #2">
<img src="https://www.fillmurray.com/300/150" alt="Test - Logo #2" class="card-img-top logo-hover">
</a>
<div class="card-body">
<p class="card-text">Test - Logo #2</p>
<div class="d-flex justify-content-between align-items-center"></div>
</div>
</div>
<div class="col-12 col-md-6 col-lg-4 col-xxl-5 img-scroll">
<div class="card shadow-sm first-image">
<a href="https://www.fillmurray.com/1000/1000" title="Test - Logo #3">
<img src="https://www.fillmurray.com/300/150" alt="Test - Logo #3" class="card-img-top logo-hover">
</a>
<div class="card-body">
<p class="card-text">Test - Logo #3</p>
<div class="d-flex justify-content-between align-items-center"></div>
</div>
</div>
</div>
<div class="col-xxl-1"></div>
<div class="col-xxl-1"></div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.1/dist/js/bootstrap.bundle.min.js"></script>
I hope, someone can help me...
The most important step is to check if an <img> element is entering the current viewport.
We can use the Intersection Observer API.
const options = {
rootMargin: "0px",
threshold: 0.5
};
const inViewPortObserver = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
let target = entry.target;
let dataSrc = target.getAttribute('data-src');
target.src = dataSrc;
target.classList.replace('lazyload', 'lazyloaded');
}
});
}, options);
By adjusting the threshold value we can define when the intersecting value returns true:
E.g treshold:0.5 => element is intersection if 50% of it's height is in viewport.
Now we can define a callback:
if(entry.isIntersecting){}
If element is in viewport – set the src attribute from data-src and toggle css classes from 'lazyload' to 'lazyloaded'.
Most lazyload libraries use a similar syntax or api concept like this:
<img data-src="https://www.fillmurray.com/480/480" class="lazyload">
The actual image src/URL is defined by a data attribute: data-src.
Lazy loading can significantly improve the overall performance and user experience by loading images only if they are really required.
The animation is done by toggling between css classes:
E.g .lazyload (not loaded yet) and lazyloaded (loaded)
.lazyload {
opacity: 0;
transform: translateY(100%);
}
.lazyloaded {
opacity: 1;
transform: translateY(0%);
}
Simple Example: using js IntersectionObserver()
const options = {
rootMargin: "0px",
threshold: 0.5
};
const inViewPortObserver = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
let target = entry.target;
let dataSrc = target.getAttribute('data-src');
target.src = dataSrc;
target.classList.replace('lazyload', 'lazyloaded');
}
});
}, options);
const images = document.querySelectorAll('.lazyload');
images.forEach(function(img, i) {
inViewPortObserver.observe(img);
})
* {
box-sizing: border-box
}
header {
margin-bottom: 40vmin;
}
main {
padding-bottom: 50em;
}
section {
margin-bottom: 20em;
}
.row {
display: flex;
}
.row>* {
flex: 1;
}
.card-img-top {
transition: 2s;
}
.lazyload {
opacity: 0;
transform: translateY(100%);
}
.lazyloaded {
opacity: 1;
transform: translateY(0%);
}
img {
aspect-ratio: 2/1;
display: block;
background-color: #ccc;
width: 100%;
max-width: 100%;
object-fit: cover;
object-position: 50% 50%;
}
<div class="row">
<header class="arbeiten">
<h2>{ Logos }</h2>
<p>Please scroll down …</p>
</header>
</div>
<main>
<section>
<div class="row">
<figure>
<img data-src="https://www.fillmurray.com/480/480" alt="Test - Logo #1" class="lazyload card-img-top logo-hover">
</figure>
<figure>
<img data-src="https://www.fillmurray.com/300/150" alt="Test - Logo #1" class="lazyload card-img-top logo-hover">
</figure>
</div>
<div class="row">
<figure>
<img data-src="https://www.fillmurray.com/300/200" alt="Test - Logo #1" class="lazyload card-img-top logo-hover">
</figure>
<figure>
<img data-src="https://www.fillmurray.com/200/300" alt="Test - Logo #1" class="lazyload card-img-top logo-hover">
</figure>
<figure>
<img data-src="https://www.fillmurray.com/400/240" alt="Test - Logo #1" class="lazyload card-img-top logo-hover">
</figure>
</div>
</section>
<section>
<div class="row">
<figure>
<img data-src="https://www.fillmurray.com/320/240" alt="Test - Logo #1" class="lazyload card-img-top logo-hover">
</figure>
<figure>
<img data-src="https://www.fillmurray.com/300/150" alt="Test - Logo #1" class="lazyload card-img-top logo-hover">
</figure>
<figure>
<img data-src="https://www.fillmurray.com/333/111" alt="Test - Logo #1" class="lazyload card-img-top logo-hover">
</figure>
<figure>
<img data-src="https://www.fillmurray.com/444/333" alt="Test - Logo #1" class="lazyload card-img-top logo-hover">
</figure>
</div>
</section>
</main>
Example 2: observe a parent element and lazyload images
The main difference: we're observing viewport intersections for parent elements like the .card class.
const options = {
rootMargin: "0px",
threshold: 0.1
};
const inViewPortObserver = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
let target = entry.target;
let img = target.querySelector('img');
let dataSrc = img.getAttribute('data-src');
img.src = dataSrc;
target.classList.add('inViewPort');
}
});
}, options);
const cards = document.querySelectorAll('.card');
cards.forEach(function(card, i) {
inViewPortObserver.observe(card);
})
* {
box-sizing: border-box
}
header {
margin-bottom: 60vmin;
}
main {
padding-bottom: 50em;
}
section {
margin-bottom: 20em;
}
.row {
display: flex;
gap: 1em;
}
.row>* {
flex: 1;
}
.card {
transition: 2s;
transform: translateY(100%);
border: 2px solid red;
opacity: 0;
}
/** optional sibling delay */
.row .card:nth-of-type(2) {
transition-delay: 0.5s;
}
.row .card:nth-of-type(3) {
transition-delay: 0.75s;
}
.row .card:nth-of-type(4) {
transition-delay: 1s;
}
.row .card:nth-of-type(5) {
transition-delay: 1.25s;
}
.row .card:nth-of-type(6) {
transition-delay: 1.5s;
}
.inViewPort {
opacity: 1;
transform: translateY(0%);
}
img {
aspect-ratio: 2/1;
display: block;
background-color: #ccc;
width: 100%;
max-width: 100%;
object-fit: cover;
object-position: 50% 50%;
}
<div class="row">
<header class="arbeiten">
<h2>{ Logos }</h2>
<p>Please scroll down …</p>
</header>
</div>
<main>
<section>
<div class="row row1">
<div class="card">
<a href="#">
<img data-src="https://www.fillmurray.com/480/480" alt="" class="lazyload card-img-top logo-hover">
</a>
</div>
<div class="card">
<a href="#">
<img data-src="https://www.fillmurray.com/300/150" alt="" class="lazyload card-img-top logo-hover">
</a>
</div>
<div class="card">
<a href="#">
<img data-src="https://www.fillmurray.com/300/222" alt="" class="lazyload card-img-top logo-hover">
</a>
</div>
<div class="card">
<a href="#">
<img data-src="https://www.fillmurray.com/300/247" alt="" class="lazyload card-img-top logo-hover">
</a>
</div>
</div>
</section>
<section>
<div class="row row2">
<div class="card">
<a href="#">
<img data-src="https://www.fillmurray.com/320/240" alt="" class="lazyload card-img-top logo-hover">
</a>
</div>
<div class="card">
<a href="#">
<img data-src="https://www.fillmurray.com/300/111" alt="" class="lazyload card-img-top logo-hover">
</a>
</div>
<div class="card">
<a href="#">
<img data-src="https://www.fillmurray.com/300/112" alt="" class="lazyload card-img-top logo-hover">
</a>
</div>
</div>
</section>
<section>
<div class="row row2">
<div class="card">
<a href="#">
<img data-src="https://www.fillmurray.com/320/240" alt="" class="lazyload card-img-top logo-hover">
</a>
</div>
<div class="card">
<a href="#">
<img data-src="https://www.fillmurray.com/300/111" alt="" class="lazyload card-img-top logo-hover">
</a>
</div>
<div class="card">
<a href="#">
<img data-src="https://www.fillmurray.com/300/112" alt="" class="lazyload card-img-top logo-hover">
</a>
</div>
</div>
</section>
They have build the gallery with gridster and scrollmagic. Scrollmagic lets you do all kind of things when scrolling.
you can checkout the package at https://scrollmagic.io
You can animate with jQuery. Here is tutorial with example.
http://talkerscode.com/webtricks/move-elements-on-page-scroll-using-jquery-and-css.php
The animation on the site that you provided is triggered when the load event on the images is emitted. The load event is emitted when an image has completed loading. This is combined with lazy loading to load the images as you scroll down on the page.
To implement something like this, you need to enable lazy loading for the images and listen for a load event on them. When the load event is emitted, use Javascript to complete the animation.
The javascript would look something like this:
$(".img-scroll").one("load", () => {
// do animation here
})
Just make sure the images have lazy loading enabled by setting their loading attribute to lazy
there is a very good library for scroll effect called AOS.I linked it down here
it .You can find setup guide at the end of the page. Just add those styles to your image or any other html tag!. Make sure that you check it out.
link to AOS library
I am using TweenMax.min.js, TimelineMax.min.js, ScrollMagic.min.js
List item
const tl = new TimelineMax();
const tl2 = new TimelineMax();
const controller = new ScrollMagic.Controller();
tl.from('#first-fig', .3, {y:200, opacity: 0});
tl.from('#second-fig', .3, {scale: 0}, "=-.5");
tl.from('#third-fig', .3, {y:200, opacity: 0});
tl2.from('#fourth-fig', .5, {y:200, opacity: 0});
tl2.from('#fifth-fig', .5, {y:200,opacity: 0});
tl2.from('#sixth-fig', .5, {y:200, opacity: 0});
const firstScene = new ScrollMagic.Scene({
triggerElement: "#second-h1"
})
.setTween(tl)
.addTo(controller);
const secondScene = new ScrollMagic.Scene({
triggerElement: "#first-img"
})
.setTween(tl2)
.addTo(controller);
#import url("https://fonts.googleapis.com/css?family=Arapey");
*,
*::after,
*::before {
margin: 0;
padding: 0;
box-sizing: inherit;
}
html {
box-sizing: border-box;
font-size: 62.5%;
}
body {
font-family: "Arapey";
font-weight: 700;
background: #dfe6e9;
}
.container {
position: relative;
}
h1 {
margin: 0 auto;
width: 100rem;
text-align: center;
font-size: 6rem;
}
.section--1 {
height: 100rem;
background: #bdc3c7;
}
.section--2 {
margin: 0 auto;
width: 100rem;
}
.images {
display: grid;
padding: 0.5rem;
margin: 2rem auto;
width: 100%;
grid-template-rows: repeat(auto-fill, 25rem);
grid-template-columns: repeat(3, 1fr);
grid-gap: 0.8rem;
grid-auto-columns: 1fr;
grid-auto-rows: 25rem;
}
.images--img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.0.2/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.0.2/TimelineMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.6/ScrollMagic.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.6/plugins/animation.gsap.min.js"></script>
<div class="container">
<section class="section--1">
<h1>Scroll down to see the animations</h1>
</section>
<section class="section--2">
<h1 id="second-h1">
hello there I love code and music
</h1>
<div class="images">
<figure class="images--fig" id="first-fig"><img src="https://images.unsplash.com/photo-1485170536212-67180b105ff6?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80" alt="" class="images--img" id="first-img"></figure>
<figure class="images--fig" id="second-fig"><img src="https://images.unsplash.com/photo-1518257678582-d5c9bb2e6ec9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=588&q=80" alt="" class="images--img"></figure>
<figure class="images--fig" id="third-fig"><img src="https://images.unsplash.com/photo-1540821924489-7690c70c4eac?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=991&q=80" alt="" class="images--img"></figure>
<figure class="images--fig" id="fourth-fig"><img src="https://images.unsplash.com/photo-1484755560615-a4c64e778a6c?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=980&q=80" alt="" class="images--img" id="fourth-img"></figure>
<figure class="images--fig" id="fifth-fig"><img src="https://images.unsplash.com/photo-1481207727306-1a9f151fca7d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80" alt="" class="images--img"></figure>
<figure class="images--fig" id="sixth-fig">
<img src="https://images.unsplash.com/photo-1517852058149-07c7a2e65cc6?ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80" alt="" class="images--img">
</figure>
</div>
</section>
<section class="section--1"></section>
</div>
Here is barebone structure similar to the example website using a tiny library #opuu/inview.
The parallax effect and animation on scroll both can be done with this same library very easily.
body {
margin: 0;
padding: 0;
}
#container {
position: relative;
width: 100%;
}
#background {
background: url('https://picsum.photos/seed/picsum/700/500');
background-size: cover;
background-position: center;
height: 150vh;
width: 100%;
}
#foreground {
background-color: blue;
transition: margin-top 0.1s;
height: 200vh;
width: 70%;
margin: 0 auto;
}
#effect {
padding: 20px;
width: 100%;
background-color: brown;
display: flex;
justify-content: space-around;
align-items: center;
}
.aos {
transform: translateY(500px);
transition: all 0.5s;
}
.aos.active {
transform: translateY(0);
transition: all 0.5s;
}
#empty {
height: 100vh;
width: 100%;
background-color: green;
}
<div id="container">
<div id="background">
Background with image
</div>
<div id="foreground">
Content that overlays the background
</div>
<div id="effect">
<img class="aos" loading="lazy" src="https://picsum.photos/seed/picsum/700/500" alt="">
<img class="aos" loading="lazy" src="https://picsum.photos/seed/picsum/700/500" alt="">
</div>
<div id="effect">
<img class="aos" loading="lazy" src="https://picsum.photos/seed/picsum/700/500" alt="">
<img class="aos" loading="lazy" src="https://picsum.photos/seed/picsum/700/500" alt="">
</div>
<div id="empty">
</div>
</div>
<script type="module">
import InView from "https://unpkg.com/#opuu/inview#1.0.2/dist/inview.js";
let hero = new InView("#background");
hero.on("enter", (event) => {
document.querySelector("#foreground").style.marginTop = `-${100 - event.percentage}vh`;
});
let effect = new InView(".aos");
let queue = 0;
effect.on("enter", (event) => {
if (queue == 0) {
event.target.style.transitionDelay = "0.2s";
event.target.classList.add("active");
queue = 1;
} else {
event.target.classList.add("active");
queue = 0;
}
});
// effect.on('exit', (event) => {
// event.target.classList.remove("active"); // you can also add remove animation
// });
</script>
Note: I am the author of this library.

How to get the images to be the same size using Isotope JS

I am using Isotope JS and I am trying to get an evenly spaced, proportional gallery layout but I am not sure what is wrong. My code isn't cooperating with isotope. I would be very grateful if someone could help me figure out what I am doing wrong.
I created a codepen if that would help as well: https://codepen.io/jaytb95/pen/vYxMGqP
$(document).ready(function() {
$grid = $('.grid').isotope({
filter: '*',
itemSelector: '.grid-item',
layoutMode: 'fitRows',
percentPosition: true
});
$filters = $('.list');
$filters.click(function() {
$value = $(this).attr('data-filter');
if ($value == 'all') {
$grid.isotope({ filter: '*' });
} else {
$grid.isotope({ filter: '.' + $value });
}
});
});
ul {
display: flex;
list-style: none;
justify-content: center;
margin-top: 25px;
}
ul > li {
margin-left: 15px;
cursor: pointer;
padding: 0.5rem 1rem;
background-color: crimson;
color: white;
font-family: 'Calibri',sans-serif;
}
.container {
max-width: 90%;
margin: 0 auto;
}
.grid {
columns: 4 25vh;
}
.grid-item img {
object-fit: cover;
width: 100%;
height: auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://unpkg.com/isotope-layout#3.0.6/dist/isotope.pkgd.min.js"></script>
<ul>
<li class="list" data-filter="all">All</li>
<li class="list" data-filter="phone">Phone</li>
<li class="list" data-filter="camera">Camera</li>
<li class="list" data-filter="watch">Watch</li>
</ul>
<div class="container">
<div class="grid">
<div class="grid-item phone">
<img src="https://picsum.photos/500/300" alt="" />
</div>
<div class="grid-item camera">
<img src="https://picsum.photos/400/200" alt="" />
</div>
<div class="grid-item watch">
<img src="https://picsum.photos/500/300" alt="" />
</div>
<div class="grid-item camera">
<img src="https://picsum.photos/400/200" alt="" />
</div>
<div class="grid-item watch">
<img src="https://picsum.photos/500/300" alt="" />
</div>
<div class="grid-item camera">
<img src="https://picsum.photos/400/200" alt="" />
</div>
<div class="grid-item watch">
<img src="https://picsum.photos/500/300" alt="" />
</div>
</div>
</div>
You should initialize Isotope after all the images have loaded. This means that you also have to include the imagesLoaded library in your code.
Also, to make the images proportional and evenly spaced, set the width of each .grid-item class to 50%, set the width of each image to calc(100% - 0.25rem), and change the layout mode to masonry. Your "image gallery" should work just fine after this:
$(document).ready(function() {
$grid = $(".grid").imagesLoaded(function() {
$grid.isotope({
filter: "*",
itemSelector: ".grid-item",
layoutMode: "masonry",
percentPosition: true
});
});
$filters = $(".list");
$filters.click(function() {
$value = $(this).attr("data-filter");
if ($value == "all") {
$grid.imagesLoaded(function() {
$grid.isotope({ filter: "*" });
});
} else {
$grid.imagesLoaded(function() {
$grid.isotope({ filter: "." + $value });
});
}
});
});
ul {
display: flex;
list-style: none;
justify-content: center;
margin-top: 25px;
}
ul > li {
margin-left: 15px;
cursor: pointer;
padding: 0.5rem 1rem;
background-color: #dc143c; /* crimson */
color: #fff; /* white */
font-family: "Calibri", sans-serif;
}
.container {
max-width: 90%;
margin: 0 auto;
}
.grid {
columns: 4 25vw;
}
.grid-item {
width: 50%;
}
.grid-item img {
object-fit: cover;
-o-object-fit: cover;
width: calc(100% - 0.25rem);
height: auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://unpkg.com/isotope-layout#3.0.6/dist/isotope.pkgd.min.js"></script>
<script src="https://unpkg.com/imagesloaded#4.1.4/imagesloaded.pkgd.min.js"></script>
<ul>
<li class="list" data-filter="all">All</li>
<li class="list" data-filter="phone">Phone</li>
<li class="list" data-filter="camera">Camera</li>
<li class="list" data-filter="watch">Watch</li>
</ul>
<div class="container">
<div class="grid">
<div class="grid-item phone">
<img src="https://picsum.photos/500/300" alt="">
</div>
<div class="grid-item camera">
<img src="https://picsum.photos/400/200" alt="">
</div>
<div class="grid-item watch">
<img src="https://picsum.photos/500/300" alt="">
</div>
<div class="grid-item camera">
<img src="https://picsum.photos/400/200" alt="">
</div>
<div class="grid-item watch">
<img src="https://picsum.photos/500/300" alt="">
</div>
<div class="grid-item camera">
<img src="https://picsum.photos/400/200" alt="">
</div>
<div class="grid-item watch">
<img src="https://picsum.photos/500/300" alt="">
</div>
</div>
</div>

How to maintain image aspect ratio in modal using flexbox?

I have an image gallery in my modal, which is styled using flexbox. The problem is that some pictures which are too large horizontally flow over and make the flexbox stretch, so the item next to it is messed up, eventhough the flex weights are set in css.
<div class="slideshow-container">
<div class="mySlides fade" style="display: block;">
<div class="numbertext">1 / 16</div>
<img src="./img/normal/image.jpg" class="galimg" style="height: 331px;">
<div class="text">Image description</div>
</div>
....
</div>
I want each image to maintain its aspect ratio. Some are landscape, some are portrait. So I thought I'd try the following:
var maxHeight = $('#modal-gallery').height()-39; // need 39px for the gallery navigation.
var maxWidth = $('#modal-gallery').width();
var ratio = maxHeight/maxWidth;
$('.galimg').each(function(i){
if ($(this).height()/$(this).width() > ratio){
$(this).width(maxWidth);
} else {
$(this).height(maxHeight);
}
});
CSS:
#modal-gallery { // this is the div surrounding the gallery
flex: 6;
display: flex;
margin-right: auto;
flex-direction: column;
justify-content: flex-start;
align-items: center;
}
.slideshow-container {
display: flex;
position: relative;
margin: 0;
}
I know the problem is probably somewhere in my JS, as I tried logging the width and height and often got 0. The html is generated dynamically through JS. I tried adding an onImgLoad function, but didn't get any result.
There is no need to do a js thing. Just fix your css. Add some styles and HTML elements. The following is the most common way to show different size images in many websites (Please also expand the snippet to see how it behaves).
#modal-gallery { // this is the div surrounding the gallery
flex: 6;
display: flex;
margin-right: auto;
flex-direction: column;
justify-content: flex-start;
align-items: center;
}
.slideshow-container {
display: flex;
position: relative;
margin: 0;
}
.mySlides{
display:block
}
.slide-image{
display:inline-block;
width:220px;
text-align:center;
vertical-align:top;
margin-bottom: 20px;
}
.img-container{
display:block;
width:200px;
}
.img-container .img{
display:table-cell;
vertical-align:middle;
text-align:center;
}
.img-container img{
max-height:200px;
max-width:200px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="slideshow-container">
<div class="mySlides fade">
<div class="slide-image">
<div class="numbertext">1 / 16</div>
<div class="img-container">
<div class="img">
<img src="https://s3-us-west-1.amazonaws.com/powr/defaults/image-slider1.jpg" class="galimg" />
</div>
</div>
<div class="text">Image description</div>
</div>
<div class="slide-image">
<div class="numbertext">1 / 16</div>
<div class="img-container">
<div class="img">
<img src="http://i.imgur.com/RRUe0Mo.png" class="galimg" />
</div>
</div>
<div class="text">Image description</div>
</div>
<div class="slide-image">
<div class="numbertext">1 / 16</div>
<div class="img-container">
<div class="img">
<img src="https://www.smashingmagazine.com/wp-content/uploads/2015/06/10-dithering-opt.jpg" class="galimg" />
</div>
</div>
<div class="text">Image description</div>
</div>
<div class="slide-image">
<div class="numbertext">1 / 16</div>
<div class="img-container">
<div class="img">
<img src="https://www.smashingmagazine.com/wp-content/uploads/2015/06/10-dithering-opt.jpg" class="galimg" />
</div>
</div>
<div class="text">Image description</div>
</div>
<div class="slide-image">
<div class="numbertext">1 / 16</div>
<div class="img-container">
<div class="img">
<img src="https://s3-us-west-1.amazonaws.com/powr/defaults/image-slider1.jpg" class="galimg" />
</div>
</div>
<div class="text">Image description</div>
</div>
<div class="slide-image">
<div class="numbertext">1 / 16</div>
<div class="img-container">
<div class="img">
<img src="http://i.imgur.com/RRUe0Mo.png" class="galimg" />
</div>
</div>
<div class="text">Image description</div>
</div>
</div>
</div>

JQuery mobile: Vertically and horizontally center multiple images using grid

I'm building an app using jquery mobile.
I want to vertically and horizontally center multiple images using grid, i want the images to be exactly in the center of the page. I'v tried everything but nothing really worked.
I want it exactly to look like whats in this pic:
Sample
and here is my code:
<div data-role="content">
<div class="ui-grid-a">
<div class="ui-block-a">
<img alt="" src="http://i.imgur.com/MIK25Fd.png" style="width: 100%;">
</div>
<div class="ui-block-b">
<img alt="" src="http://i.imgur.com/MIK25Fd.png" style="width: 100%;">
</div>
<div class="ui-block-a">
<img alt="" src="http://i.imgur.com/MIK25Fd.png" style="width: 100%;">
</div>
<div class="ui-block-b">
<img alt="" src="http://i.imgur.com/MIK25Fd.png" style="width: 100%;">
</div>
</div>
</div>
I would love if it can look exactly like the image attached.
Thank you.
You can scale the content div to take the device height:
$(document).on( "pagecontainershow", function(){
ScaleContentToDevice();
$(window).on("resize orientationchange", function(){
ScaleContentToDevice();
})
});
function ScaleContentToDevice(){
scroll(0, 0);
var content = $.mobile.getScreenHeight() - $(".ui-content").outerHeight() + $(".ui-content").height();
$(".ui-content").height(content);
}
Then use some CSS on the grid to center everything within the scaled content:
<div id="GridWrapper">
<div class="ui-grid-a centeredGrid">
<div class="ui-block-a" >
<img alt="" src="http://i.imgur.com/MIK25Fd.png" >
</div>
<div class="ui-block-b">
<img alt="" src="http://i.imgur.com/MIK25Fd.png" >
</div>
<div class="ui-block-a" >
<img alt="" src="http://i.imgur.com/MIK25Fd.png" >
</div>
<div class="ui-block-b">
<img alt="" src="http://i.imgur.com/MIK25Fd.png" >
</div>
</div>
</div>
#GridWrapper{
position: relative;
height: 100%;
}
#GridWrapper .centeredGrid{
position: absolute;
width: 380px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
DEMO
You can try with flexbox properties.
.ui-block-a,.ui-block-b{
width: 30px;
height: 30px;
margin: 5px;
}
.ui-grid-a{
display: flex;
align-items: center;
min-height: 15em;
justify-content: center;
}
For further information about flexbox
https://css-tricks.com/snippets/css/a-guide-to-flexbox/

masonry leaves a lot of spaces

I'm trying to use Masonry, but it doesn't seem to work well. It leaves a lot of empty spaces. as you can see here
I already tried various other ways to implement Masonry, but this one leans the most to the result. Can someone help this rookie?
Here what I think is important of my HTML/ CSS/ JAVASCRIPT
<script src="masonry-docs/js/masonry.pkgd.min.js"></script>
<script type="text/javascript">// Javascript
var container = document.querySelector('#masonry-grid');
var msnry = new Masonry( container, {
// options
columnWidth: 33%,
itemSelector: '.grid-item'
});</script>
.grid-item{width: 33%;}
.grid-item--width2{width: 33%;}
.grid-item--width3{width: 33%;}
*{box-sizing:border-box;}
.box-sizing:border-box;
.grid:after {
content: '';
display: block;
clear: both;
}
.grid-item {
width: 33%;
float: left;
border: 5px solid #FFFFFF;
}
.grid-sizer,
.grid-item {
width: 33%;
}
<section id="werk">
<div class="container">
<div class="grid">
<div class="item">
<div id="masonry-grid">
<div class="grid-item">
<h3>Manifesta 10</h3>
<span class="category">huisstijl</span>
<img src="images/manifesta.jpg" alt="" />
</div>
<div class="item">
<div class="grid-item grid-item--width2">
<h3>Deutsche Grammophon</h3>
<span class="category">platenhoezen</span>
<img src="images/GIF_1.gif" alt="" />
</div>
</div>
<div class="item">
<div class="grid-item grid-item--width3">
<h3>Ghent Art Book Fair</h3>
<span class="category">poster</span>
<img src="images/boekposter.png" alt="" />
</div>
</div>
<div class="item">
<div class="grid-item">
<h3>teaser masterproef</h3>
<span class="category">foto</span>
<img src="images/masterproef.png" alt="" />
</div>
</div>
<div class="item">
<div class="grid-item grid-item--width2">
<h3>Mundaneum</h3>
<span class="category">publicatie</span>
<img src="images/Mundaneum.gif" alt="" />
</div>
</div>
</div>
</div>
</div>
</div>
Your h3 Element has a margin, add this a the beginning of your CSS-Code:
h3 { margin: 0px; }
Your .grid-item has a border of 5px, change it in your CSS-Code:
.grid-item {
width: 33%;
float: left;
border: 0px solid #FFFFFF;
}

Categories

Resources