Related
I have been wanting to implement smooth scrolling in vanilla JS for some time, but could not find any adequate implementations or methods. However, I recently came across the concept of linear interpolation (LERP), which seems adequate unlike every other method.
Although content about LERP smooth scrolling seems scarce on the web, I just found two great articles (one, two) about LERP in general and an example of LERP being used for smooth scrolling on codepen.
The example, notably, seems unnecessarily complex due to a seemingly unnecessary amount of nested containers, so I created a minimal version of it shown below. The minimal version seems to be working, but I still have a few concerns and questions.
const
b = document.body,
m = document.querySelector('main'),
p = document.querySelector('p')
let
state = {
scroll: {
height: 0,
offset: 0,
speed: 0.075,
}
},
direction
document.addEventListener('DOMContentLoaded', () => {
state.scroll.height = m.getBoundingClientRect().height
b.style.height = `${Math.floor(state.scroll.height)}px`
})
b.addEventListener('wheel', (e) => {
direction = e.deltaY > 0 ? 'scrollDown' : 'scrollUp'
// renderLoop()
})
function renderLoop() {
// const
// difference = 'scrollDown' ? pageYOffset - state.scroll.offset : state.scroll.offset - pageYOffset
state.scroll.offset += Math.floor((pageYOffset - state.scroll.offset) * state.scroll.speed)
m.style.transform = `translateY(-${ state.scroll.offset }px)`
// if (difference > 20) requestAnimationFrame(renderLoop)
requestAnimationFrame(renderLoop)
}
renderLoop()
html, body {
width: 100%;
height: 100%;
margin: 0;
font-size: 48px;
}
main {
width: 100%;
position: fixed;
left: 0;
top: 0;
border: solid green 3px; box-sizing: border-box;
}
p {
width: 100%;
max-width: 500px;
position: relative;
left: 50%;
transform: translateX(-50%);
margin: 0;
border: solid red 3px; box-sizing: border-box;
}
<main>
<p>One<br>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Error soluta, quidem voluptatibus quo iusto iure adipisci, ullam quis unde dolore, nisi impedit in. Veniam, suscipit? Atque aut et incidunt aliquid. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Exercitationem labore dolore aut atque harum, quo necessitatibus molestias laborum fuga beatae explicabo laudantium asperiores doloremque optio iure, assumenda voluptate unde voluptates? Lorem ipsum dolor sit amet consectetur adipisicing elit. Amet inventore, voluptates corrupti illo impedit in. Recusandae, praesentium temporibus tempore totam cupiditate ratione maxime numquam corporis repudiandae. Veniam ullam rerum quo?</p>
<p>Two<br>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Error soluta, quidem voluptatibus quo iusto iure adipisci, ullam quis unde dolore, nisi impedit in. Veniam, suscipit? Atque aut et incidunt aliquid. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Exercitationem labore dolore aut atque harum, quo necessitatibus molestias laborum fuga beatae explicabo laudantium asperiores doloremque optio iure, assumenda voluptate unde voluptates? Lorem ipsum dolor sit amet consectetur adipisicing elit. Amet inventore, voluptates corrupti illo impedit in. Recusandae, praesentium temporibus tempore totam cupiditate ratione maxime numquam corporis repudiandae. Veniam ullam rerum quo?</p>
<p>Three<br>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Error soluta, quidem voluptatibus quo iusto iure adipisci, ullam quis unde dolore, nisi impedit in. Veniam, suscipit? Atque aut et incidunt aliquid. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Exercitationem labore dolore aut atque harum, quo necessitatibus molestias laborum fuga beatae explicabo laudantium asperiores doloremque optio iure, assumenda voluptate unde voluptates? Lorem ipsum dolor sit amet consectetur adipisicing elit. Amet inventore, voluptates corrupti illo impedit in. Recusandae, praesentium temporibus tempore totam cupiditate ratione maxime numquam corporis repudiandae. Veniam ullam rerum quo?</p>
</main>
One concern is that for some reason it breaks unless I call renderLoop from the global scope and let requestAnimationFrame run indefinitely without a killswitch, which, instinctively, does not seem like a good idea?
I am also confused by the fact that, although I am offsetting the content container via translate, there still appears to be a scrollbar that scrolls. And yet, notably, this does not appear to interfere with the effect at all. However, should LERP smooth scrolling via translate not bypass scrollbars and scrolling altogether?
Additionally, it seems as though the only purpose of setting the height of body to that of main is to make use of pageYOffset. I suspect there are better ways to approach the problem that do not involve using pageYOffset. Further, you would think that the combination of offsetting with translate and the page being scrolled would increase the rate at which the content is scrolled?
Anyways, I have just started coding again after an almost year-long absence, and I am not sure if I ever familiarized myself with requestAnimationFrame, so any information, guidance, or solutions would be greatly appreciated.
[ edit + update ]
Here is a codepen of a "working" (?) version, which can be seen below, that I created in attempt to address and solve some concerns or issues present in the version above. However, it clearly does not have the same effect due to, I believe, the offset value being a percentage instead of pixels, which was chosen in an attempt to standardize the "speed" at which it scrolls across "platforms" (i.e. devices, browsers, etc).
const
b = document.body,
m = document.querySelector('main')
let
scrollState = {
overflow: 0,
target: 0,
position: 0,
rate: 10,
speed: 0.2
}
b.addEventListener('wheel', (e) => {
scrollState.target -= scrollState.rate * (e.deltaY / 100)
if (scrollState.target > 0) scrollState.target = 0
else if (scrollState.target < -100) scrollState.target = -100
renderLoop()
})
function renderLoop() {
const
rawDiff = Math.abs(scrollState.position - scrollState.target),
direction = scrollState.position - scrollState.target < 0 ? -1 : 1,
diff = rawDiff * scrollState.speed * direction,
newPosition = scrollState.position - diff
m.style.transform = `translateY(${newPosition}%)`
scrollState.position = newPosition
if (Math.floor(rawDiff)) requestAnimationFrame(renderLoop)
}
html, body {
width: 100%;
height: 100%;
margin: 0;
font-size: 48px;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
body {
border: solid blue 4px; box-sizing: border-box;
}
main {
width: 100%;
position: fixed;
left: 0;
top: 0;
border: solid green 2px; box-sizing: border-box;
}
p {
width: 100%;
max-width: 500px;
position: relative;
left: 50%;
transform: translateX(-50%);
margin: 0;
border: solid red 2px; box-sizing: border-box;
}
<main>
<p>One<br>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Error soluta, quidem voluptatibus quo iusto iure adipisci, ullam quis unde dolore, nisi impedit in. Veniam, suscipit? Atque aut et incidunt aliquid. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Exercitationem labore dolore aut atque harum, quo necessitatibus molestias laborum fuga beatae explicabo laudantium asperiores doloremque optio iure, assumenda voluptate unde voluptates? Lorem ipsum dolor sit amet consectetur adipisicing elit. Amet inventore, voluptates corrupti illo impedit in. Recusandae, praesentium temporibus tempore totam cupiditate ratione maxime numquam corporis repudiandae. Veniam ullam rerum quo?</p>
<p>Two<br>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Error soluta, quidem voluptatibus quo iusto iure adipisci, ullam quis unde dolore, nisi impedit in. Veniam, suscipit? Atque aut et incidunt aliquid. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Exercitationem labore dolore aut atque harum, quo necessitatibus molestias laborum fuga beatae explicabo laudantium asperiores doloremque optio iure, assumenda voluptate unde voluptates? Lorem ipsum dolor sit amet consectetur adipisicing elit. Amet inventore, voluptates corrupti illo impedit in. Recusandae, praesentium temporibus tempore totam cupiditate ratione maxime numquam corporis repudiandae. Veniam ullam rerum quo?</p>
<p>Three<br>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Error soluta, quidem voluptatibus quo iusto iure adipisci, ullam quis unde dolore, nisi impedit in. Veniam, suscipit? Atque aut et incidunt aliquid. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Exercitationem labore dolore aut atque harum, quo necessitatibus molestias laborum fuga beatae explicabo laudantium asperiores doloremque optio iure, assumenda voluptate unde voluptates? Lorem ipsum dolor sit amet consectetur adipisicing elit. Amet inventore, voluptates corrupti illo impedit in. Recusandae, praesentium temporibus tempore totam cupiditate ratione maxime numquam corporis repudiandae. Veniam ullam rerum quo?</p>
</main>
#oldboy, I'm having the same issue regarding the scarcity of LERP + smooth scrolling on the web. Nevertheless, here is a slightly different approach involving smooth vertical scroll + LERP with a kill switch. It might not be perfect yet but it could be the building block to expand upon.
const slider = document.querySelector('.slider');
const track = document.querySelector('.slider-track');
let startY = 0;
let endY = 0;
let raf;
const lerp = (start,end,t) => start * (1-t) + end * t;
function update() {
startY = lerp(startY,endY,0.05);
track.style.transform = `translateY(-${startY}px)`;
raf = requestAnimationFrame(update);
if (startY.toFixed(1) === slider.scrollTop.toFixed(1)) cancelAnimationFrame(raf);
}
function move() {
endY = slider.scrollTop;
cancelAnimationFrame(raf);
raf = requestAnimationFrame(update);
}
window.addEventListener('load',update,false);
slider.addEventListener('scroll',move,false);
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.slider {
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
width: min(600px,90vw);
height: 90vh;
border: 1px solid rgba(0,0,0,0.5);
overflow-y: scroll;
}
.slider-track {
position: absolute;
width: 100%;
display: flex;
flex-direction: column;
gap: 1rem;
padding: 1rem;
}
.slider-item {
width: inherit;
height: 70vh;
border: 0.5px solid rgba(0,0,0,0.5);
display: grid;
place-items: center;
font: 900 0.85rem helvetica,sans-serif;
}
::-webkit-scrollbar { width: 1rem; }
::-webkit-scrollbar-track { border-left: 0.5px solid rgba(0,0,0,0.5); }
::-webkit-scrollbar-thumb {
border: 0.5px solid rgba(0,0,0,0.5);
border-right: none;
border-left: none;
}
<main class='slider'>
<div class='slider-track'>
<div class='slider-item'>1</div>
<div class='slider-item'>2</div>
<div class='slider-item'>3</div>
<div class='slider-item'>4</div>
<div class='slider-item'>5</div>
<div class='slider-item'>6</div>
<div class='slider-item'>7</div>
<div class='slider-item'>8</div>
<div class='slider-item'>9</div>
</div>
</main>
Overview:
create a function to run the LERP formula
const lerp = (start,end,t) => start * (1-t) + end * t;
when our project "load", do the following:
a) invoke the callback "update" & update the starting y-position aka "startY" with "lerp". "0.05" is the "easing" which can range from "0.01 to "0.99"
startY = lerp(startY,endY,0.05);
b) move our slider's "track" vertically with "translateY" + negative "startY" in pixels
track.style.transform = translateY(-${startY}px);
c) invoke "update" recursively with "requestAnimationFrame" and store it in "raf"
raf = requestAnimationFrame(update);
d) if "startY" is equal to "slider.scrollTop" to the nearest tenths then cancel "raf" (kill switch)
if (startY.toFixed(1) === slider.scrollTop.toFixed(1)) cancelAnimationFrame(raf);
lastly, whenever the "scroll" event is trigged on "slider" then:
a) invoke the callback "move" & track the current y-position aka "endY" with the "scrollTop" property on "slider"
endY = slider.scrollTop;
b) cancel "raf" (kill switch)
cancelAnimationFrame(raf);
c) invoke "update" recursively with "requestAnimationFrame"
cancelAnimationFrame(raf);
Please do drop me a comment when you improve upon this approach or your own code, I like to check'em out :)
So I when I start scrolling into my div, my initial value is 0. When I reach the bottom of the div, I want my value to be 100.
Here's an example :
var initial = 0;
var end = 100;
$('div').scroll(function() {
initial++;
console.log(initial);
});
div {
width: 200px;
height: 300px;
border: 1px solid;
overflow-y: scroll;
background-color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Temporibus exercitationem numquam assumenda alias blanditiis, neque labore eaque veritatis dignissimos, odio atque praesentium ut, itaque! Neque sed voluptas, similique ullam omnis.lorem Lorem
ipsum dolor sit amet, consectetur adipisicing elit. Soluta eos quas ea quia fuga aperiam maxime amet, a odit adipisci earum autem necessitatibus. Quidem obcaecati eveniet maxime ducimus provident saepe. Lorem ipsum dolor sit amet, consectetur adipisicing
elit. Ipsum deserunt, ipsam explicabo voluptate laborum nam odio nemo neque, libero iusto officia consequuntur dolorem quis est quod eaque? Similique, porro, et!</div>
In this example, if you check the console, When I scroll, the last value is 5, I want it to be 100
Thanks for your help !
You can set initial to be the percentage of the scrollable height
var $test = $('.test');
var scrollableHeight = $test.height() - $test[0].scrollHeight; // get amount of scroll available
$test.scroll(function() {
var $this = $(this);
var initial = $this.scrollTop() / scrollableHeight * -100; // divide the scroll top by the amount of scrollable height to get the percentage then times by -100 to make it a positive number out of 100
console.log(parseInt(initial)); // parseInt is optional - just gives you integers
});
.test {
width: 200px;
height: 300px;
border: 1px solid;
overflow-y: scroll;
background-color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="test">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Temporibus exercitationem numquam assumenda alias blanditiis, neque labore eaque veritatis dignissimos, odio atque praesentium ut, itaque! Neque sed voluptas, similique ullam omnis.lorem Lorem ipsum dolor sit amet, consectetur adipisicing elit. Soluta eos quas ea quia fuga aperiam maxime amet, a odit adipisci earum autem necessitatibus. Quidem obcaecati eveniet maxime ducimus provident saepe. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsum deserunt, ipsam explicabo voluptate laborum nam odio nemo neque, libero iusto officia consequuntur dolorem quis est quod eaque? Similique, porro, et!</div>
i wanted to capture the position of a scrolling capture area as shown in image below
so that on page reload any other scenario the state is preserved.
$(function(){
setInterval(function(){
window.location.reload();
},90000);
});
.container{
width:600px;
height:300px;
// background:red;
overflow-y:auto;
font-size:18px;
line-height: 40px;
padding-left: 14px;
position: relative;
}
.center-band{
position: fixed;
z-index: 40;
width: 100%;
height: 70px;
background: #0000003b;
top: 50%;
transform: translate(-50%, -50%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Adipisci sequi omnis officia, tempore nesciunt distinctio in inventore quia voluptate ducimus eius natus ex. Facilis excepturi distinctio sunt placeat deleniti error.
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Earum iste architecto dolores tempora officia vero, repellendus ab voluptas, eveniet dolore, cumque aliquam cum quas facilis aspernatur molestias perferendis eum nesciunt!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Eligendi fugiat impedit quam, sit, sapiente, provident praesentium beatae non nostrum optio repellendus porro laboriosam quidem ipsa itaque? Voluptatem quam pariatur dolorem.
Lorem ipsum dolor sit amet consectetur adipisicing elit. Error, quisquam similique distinctio, perferendis accusantium quidem voluptatum architecto nulla ad adipisci provident possimus voluptatem ut animi aliquid quo hic ab. Assumenda?
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Fuga, sit corporis. Vitae facilis nesciunt alias consectetur rem, exercitationem, est possimus, beatae architecto suscipit expedita provident culpa. At eum sequi omnis
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quas cum quaerat numquam ex vero, neque aliquid totam, explicabo error suscipit eius. Earum beatae voluptatum cupiditate iusto saepe quidem deserunt magnam?
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Commodi possimus excepturi dolores quasi, qui libero quia amet, ab facere quis nulla voluptatem, sunt necessitatibus! Animi voluptates quam minus odio excepturi!
<div class="center-band"></div>
</div>
below is my codepen:
https://codepen.io/eabangalore/pen/jeKQwd/
Question: i'm trying to capture the position of band area, so that on page reload my text will be same
Please Help me, thanks in advance
Use:
https://developer.mozilla.org/en-US/docs/Web/API/Window/pageYOffset to obtain the position.
https://developer.mozilla.org/it/docs/Web/API/Window/localStorage to save and retrive the position
https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo to scroll
Old Fascinated Way
As a document, is good to create a document structure of sections and titles. Every section may have an ID. So, you can use anchors to create URLS that points to specific page sections. You may create an internal navigation too using anchors.
See more: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a
My section 1
My section 2
<section id="my-section-1">
<h2>My section 1</h2>
<p>Lorem ipsum ...<p>
</section>
<section id="my-section-2">
<h2>My section 2</h2>
<p>Lorem ipsum ...<p>
</section>
You are scrolling on the .container element, while the position of the div.center-band is fixed.
To store the information you can use localStorage, cookies, URL hashes or params; or even the history.
Local Storage
It will keep the information until you close the browser.
In this snippet: https://jsfiddle.net/gatsbimantico/1tzaq5g2/ I'm using local storage.
$(function() {
var store = window.localStorage;
var featureKey = 'container.scrollTop';
function recoverScroll() {
var scroll = store.getItem(featureKey);
$('.container').scrollTop(parseInt(scroll, 10));
}
function saveScroll() {
var scroll = $('.container').scrollTop();
store.setItem(featureKey, scroll.toString());
}
if (!!store) {
recoverScroll();
$('.container').on('scroll', saveScroll);
}
});
You can do this by using two things localStorage and jquery scroll functions as follows:
$(function(){
let heightOffset =localStorage.getItem("heightOffset");
$('.container').scrollTop(heightOffset);
setInterval(function(){
heightOffset = $('.container').scrollTop();
localStorage.setItem("heightOffset", heightOffset);
window.location.reload();
},90000);
});
here before loading localStorage.setItem("heightOffset", heightOffset) sets the previous scroll offset position, further on reload you can get the initial offset position from localStorage.getItem("heightOffset"), and keep the scroll exactly at that position.
Here you can view the working example.
I suspect you want to return the scroll position back to what the User left on. This will not use the fixed position, but capture the current scroll position.
Consider the following example: https://jsfiddle.net/Twisty/0u9rdym7/14/
JavaScript
$(function() {
function recordScroll(val) {
var pos = 0;
if (typeof val !== undefined) {
pos = val;
}
console.log("Save", pos);
localStorage.setItem('scrollVal', val);
}
function getScroll() {
var pos = localStorage.getItem('scrollVal') || 0;
pos = parseInt(pos);
console.log("Get", pos);
return pos;
}
function returnToPos($t, val) {
var pos = 0;
if (typeof val === 'undefined') {
pos = getScroll();
} else {
pos = val;
}
pos = parseInt(pos);
console.log("Return", pos);
$t.scrollTop(pos);
}
$(".container").scroll(function(e) {
var pos = $(this).scrollTop();
clearTimeout($.data(this, 'scrollTimer'));
$.data(this, 'scrollTimer', setTimeout(function() {
recordScroll(pos);
console.log("Haven't scrolled in 250ms!");
}, 250));
});
returnToPos($(".container"));
recordScroll($(".container").scrollTop());
});
You will want to record the current position, get the position, and return the container to that position. As suggested, since the page will be reloading, localStorage or cookies is a good way to do this. During Scroll actions, we need to know when scrolling stops and we also want to know the scrollTop value.
When scrolling stops, we can save the value to localStorage. When reload happens, the page will collect the stored value and return the scroll to that position.
Hope that helps.
A simple solution
Attach onscroll event to your div.
function setScroll(){
document.getElementById("myDiv").scrollTop = localStorage.getItem('scrollTO')||0;
}
<body onload="setScroll()">
<div id="myDiv" onscroll="localStorage.setItem('scrollTO',this.scrollTop)">
<!-- your text goes here-->
</div>
</body>
When you scroll, the scrollTop is saved to localStorage and when you reload the page, you can read that from localStorage and scroll your page to the position from where the user left.
I'm working on a website and I've the following code :
//SlideToggle
$('a').attr('href', 'javascript:void(0)');
$('a').click(function() {
$(this).next().slideToggle();
});
$('.container div').addClass('cf');
.hidden {
display: none;
}
.container {
width: 100%;
margin: 0 auto;
}
.container div {
width: 25%;
display: inline-block;
vertical-align: top;
text-align: center;
background: lightblue;
margin: 0 0 0.25em;
padding: 25px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div>See more
<p class="hidden">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia ipsam, dolorem illum. Amet officiis dignissimos eligendi excepturi nam, aliquid architecto atque nostrum illo. Ratione nesciunt, id nulla dolores? Blanditiis, praesentium.</p>
</div>
<div>See more
<p class="hidden">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Error sint nihil labore molestias expedita corrupti ipsa iusto iure sit nisi ab nobis maxime unde voluptates magni, distinctio quae. Deserunt, incidunt.</p>
</div>
<div>See more
<p class="hidden">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Deserunt accusamus facilis tempore repellat eligendi accusantium laudantium quis, magni a soluta deleniti voluptatibus quam, est aliquid. Atque a, esse. Itaque, consequuntur.</p>
</div>
<div>See more
<p class="hidden">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aperiam, quo, possimus. Quam odit laudantium, ex alias, repellat laborum quae nobis expedita aperiam iusto iure at facilis obcaecati doloribus quis earum.</p>
</div>
<div>See more
<p class="hidden">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quam ratione doloribus laborum deleniti quae cumque quasi, repellat, ex nemo nulla corporis voluptatum vel doloremque nesciunt cupiditate, veritatis excepturi vero harum.</p>
</div>
<div>See more
<p class="hidden">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam cupiditate quisquam, dicta eligendi ut eos culpa nisi quod nesciunt vero soluta voluptates illo esse voluptatibus, ab, sint impedit repudiandae dolorum!</p>
</div>
</div>
The slideToggle is working well . However, when I slideToggle, I want this action only affect the div at the bottom and not the others. Let me show you what I want :
(I don't want to touch at div height, they have to stay like that)
Hope I'm clear. Thanks for your help !
This comes close, maybe someone is able to improve this..
//SlideToggle
$('a').attr('href','javascript:void(0)');
$('a').click(function() {
var $self = $(this);
var index = $self.parent().index();
$(this).next().slideToggle(100, function() {
var margin = $self.parent().toggleClass("active").find("p").outerHeight();
if($self.parent().hasClass("active")) {
$(".container div").eq(index + 3).css("margin-top", margin);
}
else {
$(".container div").eq(index + 3).css("margin-top", 0);
}
});
});
$('.container div').addClass('cf');
* {
box-sizing:border-box;
}
.hidden {
display: none;
}
.container {
width: 100%;
margin: 0 auto;
}
.container div {
width: 33.3333333333%;
display: inline-block;
vertical-align: top;
text-align: center;
background: lightblue;
margin:0;
padding: 25px;
position:relative;
-webkit-transition: ease-in-out, margin .1s ease-in-out;
transition: ease-in-out, margin .1s ease-in-out;
float:left;
}
.container div p {
position:absolute;
width:100%;
left:0;
padding:25px;
margin:0;
top:100%;
background: lightblue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div>See more
<p class="hidden">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia ipsam, dolorem illum. Amet officiis dignissimos eligendi excepturi nam, aliquid architecto atque nostrum illo. Ratione nesciunt, id nulla dolores? Blanditiis, praesentium.</p>
</div>
<div>See more
<p class="hidden">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Error sint nihil labore molestias expedita corrupti ipsa iusto iure sit nisi ab nobis maxime unde voluptates magni, distinctio quae. Deserunt, incidunt.</p>
</div>
<div>See more
<p class="hidden">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Deserunt accusamus facilis tempore repellat eligendi accusantium laudantium quis, magni a soluta deleniti voluptatibus quam, est aliquid. Atque a, esse. Itaque, consequuntur.</p>
</div>
<div>See more
<p class="hidden">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aperiam, quo, possimus. Quam odit laudantium, ex alias, repellat laborum quae nobis expedita aperiam iusto iure at facilis obcaecati doloribus quis earum.</p>
</div>
<div>See more
<p class="hidden">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quam ratione doloribus laborum deleniti quae cumque quasi, repellat, ex nemo nulla corporis voluptatum vel doloremque nesciunt cupiditate, veritatis excepturi vero harum.</p>
</div>
<div>See more
<p class="hidden">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam cupiditate quisquam, dicta eligendi ut eos culpa nisi quod nesciunt vero soluta voluptates illo esse voluptatibus, ab, sint impedit repudiandae dolorum!</p>
</div>
</div>
Try this :
Hide all the p tag before do Slide toggle.
$('a').click(function() {
$('p').hide();
$(this).next().slideToggle();
});
EDIT
Incorrectly marked as a duplicate, I marked it duplicate before I tested the answer on the referred question. It doesn't provide the exactly what I want, which is a sticky footer initially and only float to the bottom of the page when the content is larger than the viewport.
/EDIT
EDIT2
Found the answer over here, pure CSS and does exactly what I want.
/EDIT2
I want a sticky footer until the document height is greater than the viewport height, then it just should be at the end of the document.
The document is build up like this:
<body>
<div class="header">
<!-- content -->
</div>
<div class="page-content">
<!-- content -->
</div>
<div class="footer">
<!-- content -->
</div>
</body>
Fiddle
The .header has a height of 101px and .footer has a height of 173px.
.page-content has a variable height depending on the content.
What I want is for .footer to stick to the bottom of the viewport as long as .page-content doesn't contain enough content for the document to have a greater height than the viewport
I tried giving .page-content a min-hieght so it always overflows the viewport but that is just plain ugly.
Is this possible pure CSS or does Javascript/JQuery come in to play here?
Two relatively newer methods that can be used are using calc and flexbox. Both have decent support (above 90% without prefixes for calc and with prefixes for flexbox). Using them is pretty simple, especially compared to some of the older (and admittedly more supported) methods. If you really want to push support then viewport units can make them even simpler.
Method One - Calc:
CSS:
/* Only needed if not using vh in main */
html, body {
height: 100%;
}
header {
/* Needs to be static */
height: 70px;
}
footer {
/* Needs to be static */
height: 30px;
}
main {
/* Can use 100vh instead of 100% */
min-height: calc(100% - 70px - 30px);
}
HTML:
<header></header>
<main></main>
<footer></footer>
DEMO: codepen
Method Two - Flexbox:
CSS:
body {
display: flex;
flex-direction: column;
/* If using percent then html needs a height of 100% */
min-height: 100vh;
}
main {
flex: 1;
}
HTML:
<header></header>
<main></main>
<footer></footer>
DEMO: codepen
The flexbox version is nice because header and footer can be fluid. The flex: 1; in main makes sure that main will fill any remaining space left after header and footer take whatever they need. Calc's version is less powerful, requiring a static header and footer, but no prefixes. They both work fine for me, personally, with either autoprefixer or prefixfree making sure I don't have to worry about prefixes either way.
You are probably looking for something like Ryan Faits "HTML 5 Sticky Footer"
CSS:
* {
margin: 0;
}
html, body {
height: 100%;
}
.wrapper {
min-height: 100%;
height: auto !important;
height: 100%;
margin: 0 auto -4em;
}
.footer, .push {
height: 4em;
}
HTML:
<html>
<head>
<link rel="stylesheet" href="layout.css" ... />
</head>
<body>
<div class="wrapper">
<p>Your website content here.</p>
<div class="push"></div>
</div>
<div class="footer">
<p>Footer Content here</p>
</div>
</body>
</html>
In this example the footer will be 4em high. You will probably want to adjust this to your wishes by modifying the "margin"of the ".wrapper"and the "footer" "height"
You can use this css to your footer to make it at the bottom of viewport.
.footer {
position: absolute;
bottom: 0;
width: 100%;
height: 173px;
}
Check this out:
$(function () {
$(".large-content").hide();
$("a").click(function () {
$(".large-content").toggle();
fixHeight();
});
fixHeight();
});
function fixHeight() {
if ($(window).height() >= $(document).height())
$("body").addClass("fixed-footer");
else
$("body").removeClass("fixed-footer");
}
* {font-family: 'Segoe UI'; font-size: 10pt; margin: 0; padding: 0; list-style: none;}
p {margin: 0 0 10px;}
.header, .footer {text-align: center; color: #fff; background-color: #000;}
body.fixed-footer {padding-bottom: 2em;}
body.fixed-footer .footer {position: fixed; width: 100%; bottom: 0;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="header">
Header Section
</div>
<div class="page-content">
<p>Small Content</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellat aliquam error quas culpa, sapiente sunt asperiores impedit ipsa cupiditate tempore, molestias, vitae laboriosam suscipit pariatur odit? Cumque fugiat iste provident.</p>
<p>Click for large content!</p>
<div class="large-content">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quas est quos officia repellat debitis molestiae incidunt et consequatur ut, dicta rerum qui delectus impedit saepe suscipit explicabo dolorem at ea?</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quas est quos officia repellat debitis molestiae incidunt et consequatur ut, dicta rerum qui delectus impedit saepe suscipit explicabo dolorem at ea?</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quas est quos officia repellat debitis molestiae incidunt et consequatur ut, dicta rerum qui delectus impedit saepe suscipit explicabo dolorem at ea?</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quas est quos officia repellat debitis molestiae incidunt et consequatur ut, dicta rerum qui delectus impedit saepe suscipit explicabo dolorem at ea?</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quas est quos officia repellat debitis molestiae incidunt et consequatur ut, dicta rerum qui delectus impedit saepe suscipit explicabo dolorem at ea?</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quas est quos officia repellat debitis molestiae incidunt et consequatur ut, dicta rerum qui delectus impedit saepe suscipit explicabo dolorem at ea?</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quas est quos officia repellat debitis molestiae incidunt et consequatur ut, dicta rerum qui delectus impedit saepe suscipit explicabo dolorem at ea?</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quas est quos officia repellat debitis molestiae incidunt et consequatur ut, dicta rerum qui delectus impedit saepe suscipit explicabo dolorem at ea?</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quas est quos officia repellat debitis molestiae incidunt et consequatur ut, dicta rerum qui delectus impedit saepe suscipit explicabo dolorem at ea?</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quas est quos officia repellat debitis molestiae incidunt et consequatur ut, dicta rerum qui delectus impedit saepe suscipit explicabo dolorem at ea?</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quas est quos officia repellat debitis molestiae incidunt et consequatur ut, dicta rerum qui delectus impedit saepe suscipit explicabo dolorem at ea?</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quas est quos officia repellat debitis molestiae incidunt et consequatur ut, dicta rerum qui delectus impedit saepe suscipit explicabo dolorem at ea?</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quas est quos officia repellat debitis molestiae incidunt et consequatur ut, dicta rerum qui delectus impedit saepe suscipit explicabo dolorem at ea?</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quas est quos officia repellat debitis molestiae incidunt et consequatur ut, dicta rerum qui delectus impedit saepe suscipit explicabo dolorem at ea?</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quas est quos officia repellat debitis molestiae incidunt et consequatur ut, dicta rerum qui delectus impedit saepe suscipit explicabo dolorem at ea?</p>
</div>
</div>
<div class="footer">
Footer Section
</div>