Sticky section scrolling effect HTML - javascript

In the following pen I would like to create an effect where you have to scroll (by scrolling, not with mouse movement), all the way down until the top image is revealed, until we move to the next section.
The effect I'm trying to re-create, in case the explanation is too confusing can be found on Apple's website here
As you scroll down you'll understand.
let wrapper = document.querySelector('#wrapper');
let topLayer = wrapper.querySelector('.top');
let handle = wrapper.querySelector('.handle');
wrapper.addEventListener('mousemove', e => {
handle.style.top = e.clientY + 'px';
topLayer.style.height = e.clientY + 'px';
});
});

Here is an example using the CSS position: sticky
body {
font-family: georgia;
height: 1000px;
}
img {
display: block;
margin: 0 auto;
}
.sticky {
position: sticky;
position: -webkit-sticky;
width: 100%;
top: 25vh;
justify-content: center;
align-items: center;
color: #fff;
}
.wrapper {
width: 75%;
margin: auto;
background-color: silver;
padding: 15px;
}
.wrapper {
height: 200vh;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.0/css/bootstrap.css" rel="stylesheet"/>
<div class="wrapper bg-primary">
<div class="sticky">
<img src='https://dummyimage.com/400x100.png?text=image-1' alt='' />
</div>
</div>
<br>
<div class="wrapper bg-success">
<div class="sticky">
<img src='https://dummyimage.com/400x100.png?text=image-2' alt='' />
</div>
</div>
<br>
<div class="wrapper bg-warning">
<div class="sticky">
<img src='https://dummyimage.com/400x100.png?text=image-3' alt='' />
</div>
</div>

Related

At a road block with scroll section for my featured items on site

On my site I have a scroll section that will display watches and allow you to scroll on the section similar to what rolex does on their homepage. I created div container for the section and added a wrapper container that I was using to control the items. I also was trying to add arrows that can be used as an option to scroll just like how rolex does on theirs. Nothing is working. The items are there but the functionality isnt. Take a look at Rolex website and scroll down to their watches section on the home page. I want to do exactly that.
I tried adding JavaScript to make it functional but that did nothing for me. I even added a console.log() to see if anything would print in the browser console and got nothing. Please help.
// Select the left and right arrow buttons
const leftButton = document.querySelector('.arrow-button.left');
const rightButton = document.querySelector('.arrow-button.right');
// Select the watch items wrapper element
const watchItemsWrapper = document.querySelector('.watch-items-wrapper');
// Scroll the watch items wrapper element to the left or right when the arrow buttons are clicked
leftButton.addEventListener('click', () => {
watchItemsWrapper.scrollBy({
left: watchItemsWrapper.scrollLeft - 200, // Scroll 200 pixels to the left
behavior: 'smooth' // Use a smooth scroll transition
});
});
rightButton.addEventListener('click', () => {
watchItemsWrapper.scrollBy({
left: watchItemsWrapper.scrollLeft + 200, // Scroll 200 pixels to the right
behavior: 'smooth' // Use a smooth scroll transition
});
});
/* Watch Reel Section */
.watch-reel-container {
display: flex;
position: relative;
flex-wrap: nowrap;
overflow: scroll;
scroll-behavior: smooth;
margin-left: 230px;
}
.watch-items-wrapper {
display: flex;
flex-wrap: nowrap;
}
.watch-reel-item {
flex: 0 0 200px;
padding: 20px;
cursor: pointer;
}
.watch-reel-container img {
width: 400px;
height: 400px;
object-fit: cover;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
}
.watch-name {
margin-top: 10px;
font-size: 18px;
font-weight: bold;
text-align: center;
color: #333;
text-transform: uppercase;
}
.watch-reel-h2 {
margin-top: 150px;
margin-left: 250px;
}
.watch-reel-h2 a {
text-decoration: none;
color: #375ea1;
}
.watch-reel-h2 a:hover {
opacity: 70%;
}
.scroll-bar {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 8px;
background: #ccc;
border-radius: 4px;
}
.arrow-container {
position: absolute;
top: 50%;
transform: translateY(-100%);
display: flex;
justify-content: space-between;
width: 100%;
}
.arrow-button {
display: flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
border-radius: 50%;
background-color: black;
color: white;
font-size: 20px;
cursor: pointer;
}
.arrow-button::before {
left: 0;
content: '>';
}
.arrow-button.left::before {
right: 0;
content: '<';
}
.arrow-button:hover {
background: #333;
cursor: pointer;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css" />
<!-- Beginning of Watch Reel -->
<div class="watch-reel-h2">
<h2>Featured Watches - View all</h2>
</div>
<div class="watch-reel-container">
<div class="watch-items-wrapper">
<div class="watch-reel-item">
<img src="/images/rolex-panda.png" alt="Watch 1">
<p class="watch-name">Rolex Panda</p>
</div>
<div class="watch-reel-item">
<img src="/images/ap-1.png" alt="Watch 2">
<p class="watch-name">AP Royal Oak Offshore</p>
</div>
<div class="watch-reel-item">
<img src="/images/patek-1.png" alt="Watch 3">
<p class="watch-name">Patek Phillipe</p>
</div>
<div class="watch-reel-item">
<img src="/images/patek-1.png" alt="Watch 3">
<p class="watch-name">Patek Phillipe</p>
</div>
<div class="watch-reel-item">
<img src="/images/patek-1.png" alt="Watch 3">
<p class="watch-name">Patek Phillipe</p>
</div>
<div class="watch-reel-item">
<img src="/images/patek-1.png" alt="Watch 3">
<p class="watch-name">Patek Phillipe</p>
</div>
<div class="watch-reel-item">
<img src="/images/patek-1.png" alt="Watch 3">
<p class="watch-name">Patek Phillipe</p>
</div>
</div>
<div class="scroll-bar"></div>
<div class="arrow-container">
<button class="arrow-button left">
<i class="fa fa-arrow-left"></i>
</button>
<button class="arrow-button right">
<i class="fa fa-arrow-right"></i>
</button>
</div>
</div>
<!-- End of Watch Reel -->
Add overflow: scroll to your .watch-items-wrapper:
.watch-items-wrapper {
display: flex;
flex-wrap: nowrap;
overflow: scroll;
}
You can remove the overflow: scroll; from your .watch-reel-container, it's not needed. If you want the container to span full width then add overflow: hidden to your .watch-reel-container.
Next adjust both your scroll functions as such:
Left:
leftButton.addEventListener('click', () => {
watchItemsWrapper.scrollBy({
left: -200,
behavior: 'smooth'
});
});
Right:
rightButton.addEventListener('click', () => {
watchItemsWrapper.scrollBy({
left: 200,
behavior: 'smooth'
});
});
I think this will give you the functionality you're looking for.
If you'd like to hide the scrollbar but keep the functionality, check our this doc from w3schools.
I hope this helps!

Setting up a Slick Carousel, containing sliders as individual elements

I want to create a carousel like this one here:
https://codepen.io/newrya/pen/eYMZdKe
The catch is, I want to make an auto play carousel using "slick" and want the above slider as individual elements instead of images. This is my initial Code. So, instead of these img elements inside div having class horizontal. I want the above slider as the elements.
$('.horizontal').slick({
slidesToShow: 1,
slidesToScroll: 1,
autoplay: true,
autoplaySpeed: 100,
});
#slider img{
width: 350px;
height: 350px;
margin-right: 100px;
}
<section id="slider" style="background-color:#fefefe;height: 800px;">
<div class="horizontal">
<img src="images/imags/1.jpg" class="before_after">
<img src="images/imags/2.jpg" class="before_after">
<img src="images/imags/3.jpg" class="before_after">
<img src="images/imags/4.jpg" class="before_after">
<img src="images/imags/5.jpg" class="before_after">
<img src="images/imags/6.jpg" class="before_after">
<img src="images/imags/8.jpg" class="before_after">
<img src="images/imags/9.jpg" class="before_after">
<img src="images/imags/10.jpg" class="before_after">
<img src="images/imags/11.jpg" class="before_after">
<img src="images/imags/12.jpg" class="before_after">
<img src="images/imags/13.jpg" class="before_after">
<img src="images/imags/14.jpg" class="before_after">
<img src="images/imags/15.jpg" class="before_after">
<img src="images/imags/16.jpg" class="before_after">
</div>
</section>
I copied the codepen code and replaced it with my img elements and made some changes with the css code and pasted it in my styles sheet.
This is the code:
const slider = document.querySelector('#image-slider');
const wrapper = document.querySelector('.img-wrapper');
const handle = document.querySelector('.handle');
slider.addEventListener("mousemove", sliderMouseMove);
slider.addEventListener("touchmove", sliderMouseMove);
function sliderMouseMove(event) {
if (isSliderLocked) return;
const sliderLeftX = slider.offsetLeft;
const sliderWidth = slider.clientWidth;
const sliderHandleWidth = handle.clientWidth;
let mouseX = (event.clientX || event.touches[0].clientX) - sliderLeftX;
if (mouseX < 0) mouseX = 0;
else if (mouseX > sliderWidth) mouseX = sliderWidth;
wrapper.style.width = `${((1 - mouseX/sliderWidth) * 100).toFixed(4)}%`;
handle.style.left = `calc(${((mouseX/sliderWidth) * 100).toFixed(4)}% - ${sliderHandleWidth/2}px)`;
}
let isSliderLocked = false;
slider.addEventListener("mousedown", sliderMouseDown);
slider.addEventListener("touchstart", sliderMouseDown);
slider.addEventListener("mouseup", sliderMouseUp);
slider.addEventListener("touchend", sliderMouseUp);
slider.addEventListener("mouseleave", sliderMouseLeave);
function sliderMouseDown(event) {
if (isSliderLocked) isSliderLocked = false;
sliderMouseMove(event);
}
function sliderMouseUp() {
if (!isSliderLocked) isSliderLocked = true;
}
function sliderMouseLeave() {
if (isSliderLocked) isSliderLocked = true;
}
$('.horizontal').slick({
slidesToShow: 1,
slidesToScroll: 1,
autoplay: true,
autoplaySpeed: 100,
});
#slider img {
width: 350px;
height: 350px;
margin-right: 100px;
}
.horizontal {
margin: 0px;
padding: 0px;
box-sizing: border-box;
}
:root {
--image-slider-width: min(80vw, 768px);
--image-slider-handle-width: 50px;
}
.horizontal {
width: 100%;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
font-family: sans-serif;
}
#image-slider {
position: relative;
width: var(--image-slider-width);
overflow: hidden;
border-radius: 1em;
box-shadow: -4px 5px 10px 1px gray;
cursor: col-resize;
}
#image-slider img {
display: block;
width: var(--image-slider-width);
height: auto;
max-height: 80vh;
object-fit: cover;
pointer-events: none;
user-select: none;
}
#image-slider .img-wrapper {
position: absolute;
top: 0;
right: 0;
height: 100%;
width: 50%;
overflow: hidden;
z-index: 1;
}
#image-slider .img-wrapper img {
position: absolute;
top: 0;
right: 0;
height: 100%;
filter: grayscale(100%);
transform: scale(1.2);
}
#image-slider .handle {
border: 0px solid red;
position: absolute;
top: 0;
left: calc(50% - var(--image-slider-handle-width)/2);
width: var(--image-slider-handle-width);
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
user-select: none;
z-index: 2;
}
#image-slider .handle-circle {
width: var(--image-slider-handle-width);
height: var(--image-slider-handle-width);
color: white;
border: 2px solid white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: space-evenly;
}
#image-slider .handle-line {
width: 2px;
flex-grow: 1;
background: white;
}
#media (max-width: 768px) {
:root {
--image-slider-width: 90vw;
}
}
<section id="slider" style="background-color:#fefefe;height: 800px;">
<div class="horizontal">
<div id="image-slider">
<img src="https://images.pexels.com/photos/3923387/pexels-photo-3923387.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2">
<div class="img-wrapper">
<img src="https://images.pexels.com/photos/3923387/pexels-photo-3923387.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2">
</div>
<div class="handle">
<div class="handle-line"></div>
<div class="handle-circle">
&#171 &#187
</div>
<div class="handle-line"></div>
</div>
</div>
<div id="image-slider">
<img src="https://images.pexels.com/photos/3923387/pexels-photo-3923387.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2">
<div class="img-wrapper">
<img src="https://images.pexels.com/photos/3923387/pexels-photo-3923387.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2">
</div>
<div class="handle">
<div class="handle-line"></div>
<div class="handle-circle">
&#171 &#187
</div>
<div class="handle-line"></div>
</div>
</div>
<div id="image-slider">
<img src="https://images.pexels.com/photos/3923387/pexels-photo-3923387.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2">
<div class="img-wrapper">
<img src="https://images.pexels.com/photos/3923387/pexels-photo-3923387.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2">
</div>
<div class="handle">
<div class="handle-line"></div>
<div class="handle-circle">
&#171 &#187
</div>
<div class="handle-line"></div>
</div>
</div>
<div id="image-slider">
<img src="https://images.pexels.com/photos/3923387/pexels-photo-3923387.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2">
<div class="img-wrapper">
<img src="https://images.pexels.com/photos/3923387/pexels-photo-3923387.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2">
</div>
<div class="handle">
<div class="handle-line"></div>
<div class="handle-circle">
&#171 &#187
</div>
<div class="handle-line"></div>
</div>
</div>
</section>
For some, reason, in class "handle-circle", the code after '171' is not valid(it turns green).
The second problem I am facing is, the codepen slider doesn't work when I replaced it with the img elements. The 'mousemove' event is of no use when using it in carousels. How do I change that?
I think you might have issues with the slick mouse over binding conflicting with the mouse over your image, as a workaround you could iframe it and it will work like so
$(document).ready(function() {
$('.carousel').slick({
slidesToShow: 3,
dots: true,
centerMode: true,
});
});
html,
body {
background-color: #e74c3c;
}
.wrapper {
width: 100%;
padding-top: 20px;
text-align: center;
}
h2 {
font-family: sans-serif;
color: #fff;
}
.carousel {
width: 90%;
margin: 0px auto;
}
.slick-slide {
margin: 10px;
}
.slick-slide img {
width: 100%;
border: 2px solid #fff;
}
.wrapper .slick-dots li button:before {
font-size: 20px;
color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick-theme.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.js"></script>
<div class="wrapper">
<h2>Slick Carousel Example
<h2>
<div class="carousel">
<div>
<iframe width="100%" height="300" style="margin-top: -210px;" src="https://codepen.io/ptahume/full/YzaNzjy" allowfullscreen="allowfullscreen" allowpaymentrequest frameborder="0"></iframe>
</div>
<div> <iframe width="100%" height="300" style="margin-top: -210px;" src="https://codepen.io/ptahume/full/YzaNzjy" allowfullscreen="allowfullscreen" allowpaymentrequest frameborder="0"></iframe></div>
<div> <iframe width="100%" height="300" style="margin-top: -210px;" src="https://codepen.io/ptahume/full/YzaNzjy" allowfullscreen="allowfullscreen" allowpaymentrequest frameborder="0"></iframe></div>
<div><img src="https://picsum.photos/300/200?random=4"></div>
<div><img src="https://picsum.photos/300/200?random=5"></div>
<div><img src="https://picsum.photos/300/200?random=6"></div>
</div>
</div>
not a nice solution but will give you what you want

Issues with multiple sticky / fixed headers/divs? (Jittering and positioning on scroll)

I'm trying to make a site with multiple sections. There are logos, that should take up the full screen. Then, as the user scrolls down, the logos should get smaller and shrink to the top of the screen, staying fixed to the top. They should push the section contents down so that they are fully visible.
The user can continue scrolling down to the next section. It should once again be the full page height, taking up the user's entire screen. It should push the previous logo header up out of the way, and repeat the same process, as the user scrolls down, it should get smaller, moving to the top of the screen, leaving space for the contents of the section.
However, unfortunately, the headers seem to be very jittery when I try to scroll down. The scrolling can even get stuck without moving the scrollbar with the mouse.
I have also found that after I scroll down past the second section, the first header pops up again.
Here is my site, with the minimal code to reproduce this problem:
The Site
The code is mainly copied from two w3schools tutorials, I have been trying to combine the two:
https://www.w3schools.com/howto/howto_js_sticky_header.asp
https://www.w3schools.com/howto/howto_js_shrink_header_scroll.asp
Any help would be greatly appreciated, and if anyone has any ideas on how this could be fixed, please, let me know!
Update: I've figured out that the issue seems to be that the scroll offset, once the header shrinks, ends up being lower than the offset required to shrink the header. So it cycles and jitters between shrunk and not shrunk. How do I fix this?
Code (No images, please open site link to test):
// When the user scrolls down 50px from the top of the document, resize the header's font size
window.onscroll = function() {scrollFunction()};
function scrollFunction() {
console.log(document.documentElement.scrollTop);
if (document.body.scrollTop > 500 || document.documentElement.scrollTop > 500) {
document.getElementById("title").style.fontSize = "24px";
document.getElementById("title").style.height = "25vh";
document.getElementById("title").style.position = "fixed";
} else {
document.getElementById("title").style.fontSize = "96px";
document.getElementById("title").style.height = "100vh";
document.getElementById("title").style.position = "sticky";
}
if (document.body.scrollTop > 100 || document.documentElement.scrollTop > 100) {
document.getElementById("title").classList.add("sticky");
document.getElementById("title").style.fontSize = "12px";
document.getElementById("title").style.height = "10vh";
} else {
document.getElementById("title").classList.remove("sticky");
document.getElementById("title").style.fontSize = "96px";
document.getElementById("title").style.height = "100vh";
}
if (document.body.scrollTop > 960 || document.documentElement.scrollTop > 960) {
document.getElementById("title1").classList.add("sticky");
document.getElementById("l2").style.height = "50px";
document.getElementById("title1").style.height = "10vh";
} else {
document.getElementById("title1").classList.remove("sticky");
document.getElementById("l2").style.height = "500px";
document.getElementById("title1").style.height = "100vh";
}
}
:root{
--acol: #ffffff;
--bcol: #eeeeee;
--ccol: #dddddd;
--dcol: #999999;
}
html, body{
margin: 0px;
padding: 0px;
height: 100%;
text-align: center;
}
#bodycontainer{
display: flex;
}
#main{
width: 95vw;
height: 100%;
}
/* CARDS AND MAIN SCREEN*/
.title, #title, #title1{
background: var(--bcol);
width: 95vw;
overflow: visible;
display: flex;
justify-content: center;
margin: 0;
align-items: center;
position: sticky;
top: 0;
transition: 0.25s;
}
section{
width: 95vw;
}
#container{
background: var(--acol);
width: 100%;
display: flex;
flex-wrap: wrap;
}
.card{
flex: 1 0 21%;
max-width: 250px;
margin: 5px;
cursor: help;
}
.logo.two, #l2{
width: 50%;
height: 50px;
position: sticky;
position: -webkit-sticky;
display: flex;
top: 70px;
}
/*SIDEBAR*/
#sidebar{
background: var(--ccol);
position: fixed;
margin-left: 95vw;
width: 5vw;
height: 100%;
text-align: center;
font-family: "Helvetica";
display: flex;
align-items: center;
}
#circ{
width: 25px;
height: 25px;
background: var(--acol);
border-radius: 100px;
margin-left: auto;
margin-right: auto;
z-index: 999;
}
#tabs{
background: var(--bcol);
width: 25px;
margin-left: auto;
margin-right: auto;
height: fit-content;
border-radius: 25px;
}
.tab{
display: block;
width: 100%;
line-height: 25px;
z-index: 1;
}
#wrap{
position: absolute;
width: 5vw;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="style.css" rel="stylesheet">
<script src="script.js"></script>
</head>
<body>
<!--MAIN CONTENT-->
<div id="bodycontainer">
<div id="main">
<!--ROLAND-->
<section>
<h1 class="title" id="title">Roland PN-D10 Series</h1>
<div id="container">
<img src="PN-D10-01_Vector_2X.png" class="card">
<img src="PN-D10-01_Vector_2X.png" class="card">
<img src="PN-D10-01_Vector_2X.png" class="card">
</div>
</section>
<!--DAVID GARFIELD-->
<section>
<h1 class="title" id="title1"><img class="logo two" id="l2" src="DGT.svg"></h1>
<div id="container">
<img src="David_Garfield_Vector_2X.png" class="card">
<img src="David_Garfield_Vector_2X.png" class="card">
<img src="David_Garfield_Vector_2X.png" class="card">
</div>
</section>
<img src="David_Garfield_Vector_2X.png" class="card">
<img src="David_Garfield_Vector_2X.png" class="card">
<img src="David_Garfield_Vector_2X.png" class="card">
<img src="David_Garfield_Vector_2X.png" class="card">
<img src="David_Garfield_Vector_2X.png" class="card">
<img src="David_Garfield_Vector_2X.png" class="card">
<img src="David_Garfield_Vector_2X.png" class="card">
<img src="David_Garfield_Vector_2X.png" class="card">
<img src="David_Garfield_Vector_2X.png" class="card">
<img src="David_Garfield_Vector_2X.png" class="card">
<img src="David_Garfield_Vector_2X.png" class="card">
<img src="David_Garfield_Vector_2X.png" class="card">
<img src="David_Garfield_Vector_2X.png" class="card">
</div>
<!--SIDEBAR-->
<div id="sidebar">
<div id="wrap">
<div id="circ"></div>
</div>
<div id="tabs">
<a class="tab" href="#a">A</a>
<a class="tab" href="#b">B</a>
<a class="tab" href="#c">C</a>
<a class="tab" href="#d">D</a>
</div>
</div>
</body>
</html>
Thanks!

Add image below a certain class of element using css

What I want to do:
I want to add a "walkingMan" image under an element when its class is changed to activeCell. I know how to do it when the image is added to the front or back of the element using pseudo class, but as far as I know, there isn't something like :below that I can use to achieve the same effect. Is there a way in css I can use to micmic this?
What I have done:
I have added image below every upper cell and make it visible when the class is changed to activeCell. But I hope to find a more simple solution.
What it looks like:
Code: Simplified Code Example
You can use a single pseudo element on the .cell element and place a background image on it when it's active.
let activeIndex = 0;
const cells = [...document.querySelectorAll('.cell')];
setInterval(() => {
cells.forEach(cell => {
cell.classList.remove('activeCell')
});
cells[activeIndex].classList.add('activeCell');
activeIndex = activeIndex === cells.length - 1 ? 0 : (activeIndex + 1);
}, 300)
.cell {
display: inline-block;
border: 1px solid black;
margin-bottom: 1.2em;
}
.activeCell {
background-color: lightgrey;
position: relative;
}
.activeCell::after {
content: "";
position: absolute;
width: 1em;
height: 1em;
top: 1.3em;
left: calc(50% - .5em); /* Center the stickman. Position it half of its width before the parent center*/
background-image: url('https://www.shareicon.net/data/512x512/2016/01/17/704754_people_512x512.png');
background-size:cover; /* Scale the stickman to completely cover the background area. */
}
<div>
<div class='top'>
<a class='cell'>One</a>
<a class='cell'>One</a>
<a class='cell'>One</a>
<a class='cell'>One</a>
</div>
<div class='bottom'>
<a class='cell'>One</a>
<a class='cell'>One</a>
<a class='cell'>One</a>
<a class='cell'>One</a>
</div>
</div>
What about this: https://jsfiddle.net/147prwy5/3/
HTML
<div class="cell active">
<a>One</a>
<img src="https://www.shareicon.net/data/512x512/2016/01/17/704754_people_512x512.png" alt="walkingMan" />
</div>
<div class="cell">
<a>One</a>
<img src="https://www.shareicon.net/data/512x512/2016/01/17/704754_people_512x512.png" alt="walkingMan" />
</div>
<div class="cell">
<a>One</a>
<img src="https://www.shareicon.net/data/512x512/2016/01/17/704754_people_512x512.png" alt="walkingMan" />
</div>
<div class="cell active">
<a>One</a>
<img src="https://www.shareicon.net/data/512x512/2016/01/17/704754_people_512x512.png" alt="walkingMan" />
</div>
CSS
.cell {
display: inline-block;
}
.cell a {
border: 1px solid black;
}
.cell.active a {
background-color: lightgrey;
}
.cell img {
width: 20px;
height: 20px;
display: none;
}
.cell.active img {
margin-top: 5px;
width: 20px;
height: 20px;
display: block;
}
I've never been a fan of the ::before and ::after pseudo classes mainly because I've personally noticed some oddities when trying to position things in Chrome vs IE (damn it IE!). Since most people here are going to give a solution using these pseudo classes (because that's somewhat what you asked) I thought I'd give a different solution using flexbox and more divs.
Not the most optimal for download size but I do like that it's not absolute positioning elements and if the squares get bigger or smaller it's pretty easy to handle that as a scss variable at the top of the file. This all uses only two values, your padding between boxes and the size of the boxes so it should be easy to update and maintain.
Anyway, have fun! Awesome question by the way :-)
.blocks {
display: flex;
}
.block {
flex: 0 0 20px;
margin: 0px 5px;
display: flex;
flex-direction:column;
}
.block > .square {
flex: 0 0 20px;
margin: 5px 0px;
background: grey;
}
.block > .space {
flex: 0 0 20px;
margin: 5px 0px;
}
.block.activeCell > .space {
background: green;
}
<div class="blocks">
<div class="block activeCell"><div class="square"></div><div class="space"></div></div>
<div class="block"><div class="square"></div><div class="space"></div></div>
<div class="block"><div class="square"></div><div class="space"></div></div>
<div class="block"><div class="square"></div><div class="space"></div></div>
</div>
<div class="blocks">
<div class="block"><div class="square"></div></div>
<div class="block"><div class="square"></div></div>
<div class="block"><div class="square"></div></div>
<div class="block"><div class="square"></div></div>
</div>
Using jQuery you can toggle the class upon clicking with this:
$('.cell').click(function() { //catch clicks on .cell
$('.cell').removeClass('activeCell'); //remove class "activeCell" from all
$(this).addClass('activeCell'); //add class "activeCell" to .cell clicked
});
Apply position: relative; to .top and .bottom:
.top,
.bottom {
position: relative;
}
And use the psuedoclass :before to create a image under the .activeCell
.activeCell:before {
content: "";
position: absolute;
bottom: -20px;
height: 20px;
width: 20px;
background-image: url("https://www.shareicon.net/data/512x512/2016/01/17/704754_people_512x512.png");
background-size: 20px 20px;
}
And remove this:
.walkingMan {
width: 20px;
height: 20px;
display: inline-block
}
And this:
<img src="https://www.shareicon.net/data/512x512/2016/01/17/704754_people_512x512.png" alt="walkingMan" class='walkingMan'/>
And to add space between the divs .top and .bottom put a <br> between them.
$('.cell').click(function() {
$('.cell').removeClass('activeCell');
$(this).addClass('activeCell');
});
.cell {
display: inline-block;
border: 1px solid black;
cursor: pointer;
}
.top,
.bottom {
position: relative;
}
.activeCell {
background-color: lightgrey;
}
.activeCell:before {
content: "";
position: absolute;
bottom: -20px;
height: 20px;
width: 20px;
background-image: url("https://www.shareicon.net/data/512x512/2016/01/17/704754_people_512x512.png");
background-size: 20px 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div>
<div class='top'>
<a class='cell activeCell'>One</a>
<a class='cell'>One</a>
<a class='cell'>One</a>
<a class='cell'>One</a>
</div>
<br>
<div class='bottom'>
<a class='cell'>One</a>
<a class='cell'>One</a>
<a class='cell'>One</a>
<a class='cell'>One</a>
</div>
</div>
add .RunManActive Class for Active element
//clicking add active Class
$(".RunMan").click(function() {
$(".RunMan").removeClass('RunManActive');
$(this).toggleClass('RunManActive');
});
//timing add active Class
var i=0;
var $elm=$(".Animate");
setInterval(function(){
$elm.removeClass('RunManActive');
$elm.eq(i).toggleClass('RunManActive');
i=$elm.length<=i?0:i+1;
}, 1000);
.RunMan{
width:35px;
height:35px;
background-color:lightgray;
border:3px solid #fff;
float:left;
position: relative;
}
.RunManActive{
background-color:#eee;
border:3px solid lightgray;
}
.RunManActive > div{
width:35px;
height:35px;
position: absolute;
background-image:url(http://www.iconsfind.com/wp-content/uploads/2013/11/Objects-Running-man-icon.png);
background-size:cover;
top:100%;
margin-top:5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="RunMan"><div></div></div>
<div class="RunMan RunManActive"><div></div></div>
<div class="RunMan"><div></div></div>
<div class="RunMan"><div></div></div>
<div class="RunMan"><div></div></div>
<br><br><br><br><br><br>
<div style=" width:100%">
<div class="Animate RunMan"><div></div></div>
<div class="Animate RunMan "><div></div></div>
<div class="Animate RunMan"><div></div></div>
<div class="Animate RunMan"><div></div></div>
<div class="Animate RunMan"><div></div></div>
You can do something like this, using CSS only. With :target selector you can apply a style to the element you need to hide / show.
.container {
display: inline-block;
width: 100px;
height: 200px;
}
.link {
display: block;
width: 100px;
height: 100px;
background: #ccc;
}
.walking-man {
display: none;
width: 100px;
height: 100px;
background: red;
}
#p1:target {
display: block;
}
#p2:target {
display: block;
}
#p3:target {
display: block;
}
#p4:target {
display: block;
}
height: 90px;
float: left;
}
.walking-man img {
width: 100%;
}
.walkin-man:target {
display: block;
}
<div class="container">
<div id="p1" class="walking-man"></div>
</div>
<div class="container">
<div id="p2" class="walking-man"></div>
</div>
<div class="container">
<div id="p3" class="walking-man"></div>
</div>
<div class="container">
<div id="p4" class="walking-man"></div>
</div>

Scroll div content on mouse move

I have a little trouble with scrolling the div content only on mouse move. So no scrollbars are shown etc.
So I have 17 items. Every item is square 50x50 px. Mask is 300x50. So my mask is overflow: hidden and itemsWrapper has width of all subitems. I want to make scroll items horizontally on mousemove event. Can enyone give me some advice on this?
For now I have the following code:
$(document).ready(function() {
$('#navMask').on('mousemove', function(e) {
var leftOffset = $(this).offset().left;
$('#itemsWrapper').css('left', -e.clientX + leftOffset);
console.log($(this).outerWidth() + ' - ' + $(this)[0].scrollWidth);
});
});
#navMask {
position: relative;
overflow: hidden;
background: #ccc;
margin: 0 5px;
width: 300px;
height: 50px;
}
#tabWrapper {
position: absolute;
margin-left: 0;
}
.tab {
width: 50px;
height: 50px;
float: left;
background: beige;
}
.tab:hover {
background: #e4e4a1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id='navMask'>
<div id='itemsWrapper'>
<div class='item'>1</div>
<div class='item'>2</div>
<div class='item'>3</div>
<div class='item'>4</div>
<div class='item'>5</div>
<div class='item'>6</div>
<div class='item'>7</div>
<div class='item'>8</div>
<div class='item'>9</div>
<div class='item'>10</div>
<div class='item'>11</div>
<div class='item'>12</div>
<div class='item'>13</div>
<div class='item'>14</div>
<div class='item'>15</div>
<div class='item'>16</div>
<div class='item'>17</div>
</div>
</div>
Also the number of items can be dynamically changed so I have another trouble to make it working.
Is this almost what you intends??
Just add the following style rules:
#itemsWrapper {
position: absolute;
}
.item {
width: 100px;
display: inline-block;
}
Demo
$(document).ready(function() {
$('#navMask').on('mousemove', function(e) {
var leftOffset = $(this).offset().left;
$('#itemsWrapper').css('left', -e.clientX + leftOffset);
console.log($(this).outerWidth() + ' - ' + $(this)[0].scrollWidth);
});
});
#navMask {
position: relative;
overflow: hidden;
background: #ccc;
margin: 0 5px;
width: 300px;
height: 50px;
}
#tabWrapper {
position: absolute;
margin-left: 0;
}
.tab {
width: 50px;
height: 50px;
float: left;
background: beige;
}
.tab:hover {
background: #e4e4a1;
}
#itemsWrapper {
position: absolute;
}
.item {
width: 100px;
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id='navMask'>
<div id='itemsWrapper'>
<div class='item'>1</div>
<div class='item'>2</div>
<div class='item'>3</div>
<div class='item'>4</div>
<div class='item'>5</div>
<div class='item'>6</div>
<div class='item'>7</div>
<div class='item'>8</div>
<div class='item'>9</div>
<div class='item'>10</div>
<div class='item'>11</div>
<div class='item'>12</div>
<div class='item'>13</div>
<div class='item'>14</div>
<div class='item'>15</div>
<div class='item'>16</div>
<div class='item'>17</div>
</div>
</div>

Categories

Resources