I wrote code to make the logo inside my nav-bar expand-contract when I scroll, much like how the Wall Street Journal website works. However, when I scroll it now causes the logo and the other elements inside the nav-bar wiggle/vibrate.
Jquery:
$(window).on('scroll', function () {
var scrollTop = $(window).scrollTop();
if (scrollTop > 50) {
$('#logo').stop().animate({height: "50px"},100);
$('#nav').css({height: "110px"});
}
else {
$('#logo').stop().animate({height: "70px"},100);
$('#nav').css({height: "130px"});
}
});
CSS:
#logo {
height: 70px;
width: auto;
margin: auto;
display: block;
margin: auto;
}
#nav{
display: block;
max-width: 100%;
height: 120px;
position: relative;
margin: 0;
background-color: rgba(249,249,249,1);
font-family: MyriadPro-RegularImport;
}
I would recommend using jQuery to add a class, then use CSS transitions for the animation:
$('#logo').addClass('scrolled');
CSS:
#logo {
height: 70px;
transition: all 200ms ease-out; // using 'all' so that all properties are animated
}
#logo.scrolled {
height: 50px;
}
CSS animations will be smoother and easier to troubleshoot.
Related
Hoping for a little guidance. I'm making a "slide up" menu for a site i'm using and I have it working, except it's not responsive. Ideally, i'd like to have it so whatever I put in the content under "Book Now" would be hidden no matter the size, while keeping "Book Now" shown.
The way I have it set up now, I have to be very verbose about heights, and it doesn't seem to really want to work on mobile.
Hoping you kind folks could point me in the right direction of what CSS I actually need to make this work!
Here is the JSFiddle:
https://jsfiddle.net/yg13exft/
<style>
/* footer fixed Menu stuff */
.bottomNav{
overflow: hidden;
position: fixed;
bottom: -210px;
width: 100%;
transition: all .7s ease-in-out;
z-index: 9999;
}
.tipBar{
text-align: center;
transition: all .7s ease-in-out;
}
.tipBar a{
color: #6c0505;
background: orange;
display: inline-block;
padding: 5px 15px 5px 15px;
}
.menuBar{
background-color: #6c0505;
display: grid;
grid-template-columns: auto auto;
justify-content: center;
padding-top: 10px;
height: 100%;
}
.bottomNav p{
color: black;
}
.displayNone{
display: none;
}
.tipToggleAnim{
bottom: 46px;
}
.bottomMenuAnim{
bottom: 0;
}
.rightCol img{
max-height: 200px;
}
</style>
<div class="bottomNav" id="bottomNav">
<div class="tipBar" id="tipBar">
<a id="bookNowButton" class="animate__animated animate__backInUp">
Book Now!
</a>
</div>
<div id="dialog" class="menuBar" >
<div class="leftCol">
<p>
TEST TEXT HERE! :)
</p>
</div>
<div class="rightCol">
<img src="https://images.unsplash.com/photo-1589883661923-6476cb0ae9f2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1374&q=80" alt="cat">
</div>
</div>
</div>
<script>
let toggledVar = false;
function popupMenu(){
let menuToggle = document.getElementById("bottomNav");
let divButton = document.getElementById("tipBar");
if (toggledVar == true){
toggledVar = !toggledVar;
menuToggle.classList.remove('bottomMenuAnim');
}
else {
toggledVar = !toggledVar;
menuToggle.classList.add('bottomMenuAnim');
}
}
let buttonTest = document.getElementById("bookNowButton");
buttonTest.addEventListener("click", popupMenu, false);
</script>
Thank you.
I would use clientHeight to get the height of the dialog section and then set that as the bottom attribute so it will always be hidden. That way no matter what the height of the content, it will always know how many pixels to set bottom to and hide the div, but keep the Book Now showing.
There is a window load event because we need the DOM to fully load before we retrieve dialog div height.
Then, we use animate to smooth the change of the bottom attribute. Animate takes two parameters, the keyframes and the options. In the options, fill makes the animation run and stay in its end state. You can adjust the duration to fit your liking.
// We wait for the page to fully load, then we can grab the height of the div
window.addEventListener('load', function() {
// Toggle boolean
let toggledVar = false;
// Set toggle to Book now button
let menuToggle = document.getElementById("bookNowButton");
// Get bottomNav section
let bottomNav = document.getElementById("bottomNav");
// Get the height of the div
let hiddenSection = document.getElementById("dialog").clientHeight;
// Set bottom css attribute
bottomNav.style.bottom = `-${hiddenSection}px`;
function popupMenu(){
if (toggledVar == false) {
// Set bottom css attribute to 0px to reveal it
bottomNav.animate([
// keyframes
{ bottom: `-${hiddenSection}px` },
{ bottom: '0px' }
], {
duration: 1000,
fill: 'forwards'
});
toggledVar = true;
} else {
// Set bottom css attribute to hide it
bottomNav.animate([
// keyframes
{ bottom: '0px' },
{ bottom: `-${hiddenSection}px` }
], {
duration: 1000,
fill: 'forwards'
});
toggledVar = false;
}
}
menuToggle.addEventListener('click', popupMenu);
});
* {
box-sizing: border-box;
}
html, body {
padding: 0;
margin: 0;
width: 100%;
min-height: 100vh;
}
#bottomNav {
max-width: 100%;
position: fixed;
overflow: hidden;
left: 0px;
}
#bookNowButton {
display: block;
margin: 0 auto;
text-align: center;
padding: 1rem;
max-width: 200px;
background-color: yellow;
cursor: pointer;
}
#dialog {
background-color: #6c0505;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 1rem;
padding: 1rem;
}
.rightCol img {
max-width: 100%;
}
<div id="bottomNav">
<span id="bookNowButton">Book Now!</span>
<div id="dialog">
<div class="leftCol">
<p>
TEST TEXT HERE! :)
</p>
</div>
<div class="rightCol">
<img src="https://images.unsplash.com/photo-1589883661923-6476cb0ae9f2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1374&q=80" alt="cat">
</div>
</div>
</div>
I have am restricting the body to be the viewport's height and setting overflow: hidden on it. I am using jQuery to slide in a div that is absolutely positioned outside of the viewable area. The div that slides in is larger than the viewport and I would like for its contents to be scrollable within the viewport window.
Here's my fiddle: https://jsfiddle.net/hvew0qx4/1/
HTML:
<div class='buttons'>
<button id="toggle-results">Show Results</button>
</div>
<div class="map general-styling"></div>
<div id="results-area" class='movable'>
<div class="results general-styling"></div>
</div>
CSS:
body {
height: 100vh;
overflow: hidden;
position: relative;
}
.general-styling {
box-sizing: border-box;
width: 100%;
border-width: 10px;
border-style: solid;
}
.movable {
transition: all 0.3s ease;
position: absolute;
z-index: 44;
width: 100vw;
min-height: 100vh;
background-color: white;
overflow-y: scroll;
}
.map {
background-color: red;
border-color: pink;
height: 100vh;
}
.results {
background-color: blue;
border-color: orange;
height: 1000px;
}
.buttons {
position: absolute;
z-index: 1000;
top: 40px;
right: 40px;
}
JavaScript:
var $toggleResultsBtn = $('#toggle-results');
var $resultsArea = $('#results-area');
var $body = $('body');
$('.movable').css('top', $body.height());
$toggleResultsBtn.on('click', function(){
$toggleResultsBtn.text(function(i, text){
return text === "Show Results" ? "Hide Results" : "Show Results";
});
$resultsArea.css('top', function(i, value){
return value === '0px' ? $body.height() : '0px';
});
});
Set the height of the inner div to that of its container, and then add the property overflow-y: scroll to it.
Like so:
.container {
height: 200px;
overflow: hidden;
}
.elem {
height: 200px;
overflow-y: scroll;
}
If you want the div to scroll down at least 1000px (you want a scrollbar without any content in your div), you may want the outer div to have overflow-y set to scroll, like so:
.container {
height: 200px;
overflow-y: scroll;
}
.elem {
height: 1000px;
}
EDIT: I played around with your fiddle, and it looks like the biggest thing holding you back from what you are looking for is that you are using min-height for your .moveable div.
Change it to:
.movable {
transition: all 0.3s ease;
position: absolute;
z-index: 44;
width: 100vw;
height: 100vh; /* Change was made on this line */
background-color: white;
overflow-y: scroll;
}
min-height allows your div to grow. You clearly don't want that here, since if the div can grow, there is no need for scrolling.
EDIT 2: Added bonus - to get the scrollbar back from the edge of the screen, override the default margin given to the body:
body {
margin: 0;
}
EDIT 3: Here's an updated JSFiddle: https://jsfiddle.net/anishgoyal/hvew0qx4/4/
I want to create a website with a single fixed-width centered column and an additional fixed-width sidebar that is position: fixed on the left. When the window is large, this works perfectly, but when I resize the window, they begin to overlap when there's plenty of room left on the right side of the window. For example:
I'd like the center div to be positioned in the center until it runs into the sidebar, at which point I'd like it to have a more fluid responsive design, where the sidebar starts to push the div to the right as you resize the window. For example:
The only solution I'm aware of is something like this (using the jQuery resize event and adding a class to the center column when the window resizes small enough):
var SMALL_WINDOW_SIZE = 560;
function checkWindowSize() {
var $content = $("#content");
if ($(this).width() < SMALL_WINDOW_SIZE && !$content.hasClass("smallWindow")) {
$content.addClass("smallWindow");
} else if ($(this).width() >= SMALL_WINDOW_SIZE && $content.hasClass("smallWindow")) {
$content.removeClass("smallWindow");
}
}
$(document).ready(function() {
checkWindowSize();
});
$(window).resize(function() {
checkWindowSize();
});
#sidebar {
background: orange;
width: 100px;
height: 200px;
position: fixed;
top: 10px;
left: 10px;
}
#content {
background: blue;
width: 300px;
height: 350px;
margin: 0px auto;
}
.smallWindow {
float: left;
margin-left: 120px !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id='sidebar'></div>
<div id="content"></div>
I can't help but feel there should be a pure CSS solution or one that uses less or more elegant JavaScript. Is there such a thing?
This isn't by any means the best way of achieving the desired effect with CSS, but it's the methodology behind using CSS media queries to adapt layout that I want to convey.
Obviously if this meets your needs, you'll want to adjust the numbers/widths to suit your case.
*, :before, :after{
box-sizing: border-box;
}
body {
margin: 0;
}
.wrapper {
position: relative;
padding: 20px;
}
.sidebar, .main {
padding: 20px
}
.sidebar {
position: fixed;
top: 20px;
left: 20px;
width: 200px;
background: goldenrod;
color: white;
height: 50vh;
}
.main {
margin-left: 220px;
background: mediumblue;
color: white;
height: 200vh;
}
#media (min-width: 1050px){
.main{
margin: 0 220px 0 220px;
}
}
<div class="wrapper">
<div class="sidebar">
Sidebar
</div>
<div class="main">
Main
</div>
</div>
ยป JSBin
I am trying to animate a div upwards when a user hovers on the div.
I am able to animate the div making it bigger, however the animation happens downwards. I am trying to keep the bottom of the div remain in the same place, and have a smooth animating increasing the size of the div upwards.
See jsfiddle here which demonstrates what my code is currently doing.
Please see code below:
.box {
height: 170px;
padding-bottom: 15px;
width: 50%;
}
.content {
background-color: #e3e4e6;
height: 100%;
text-align: center;
}
.content:hover {
height: 110%;
}
<div class="box">
<div class="content">TEST</div>
</div>
You can do this using transform:scaleY() and set the transform-origin to bottom. I also put a margin-top:100px to see the effect better. Also you can use transition to make the scale smoother
You also need to scale back the text.
See here: jsfiddle
You need to scale the text back to it's original state in the same time that you scale the div. so if you scale the div 2 times. You need to scale back the text with 1/2 , same if you scale 3 times...scale back with 1/3
In this case you enlarge .content by 1.5 so you need to scale down the text inside by 1/1.5 = 0.66
Code:
.box {
height: 170px;
padding-bottom: 15px;
width: 50%;
}
.content {
background-color: #e3e4e6;
height: 100%;
text-align: center;
margin-top: 300px;
transition:0.3s;
}
.content:hover p {
transform: scaleY(0.66)
}
.content:hover {
transform: scaleY(1.5);
transform-origin: bottom;
}
<div class="box">
<div class="content">
<p>
TEST
</p>
</div>
</div>
Try it like this (I have no other idea...): You can give to the class "box" a bigger height (I put a red border around, so you can see it) than the class "content". After that, you can use flexbox, to put the class "content" on the bottom. After that, you can do it with hover to change your heigth upwards and fill it. With transition you can make a nice animation. I hope this is good enough. Perhaps there is also a way with jQUery at the moment I havn't got an idea. Let me know, if this helps you (I'm not sure if I understanded the question well) - Cheers. (Important: This heights and so on are just random values for testing)
.box {
display: flex;
justify-content: flex-end;
flex-direction: column;
height: 100px;
border: 1px solid red;
}
.content {
background-color: #e3e4e6;
height: 50px;
width: 100%;
text-align: center;
-webkit-transition: height 1s;
/* Safari */
transition: height 1s;
}
.content:hover {
height: 100%;
}
<div class="box">
<div class="content">TEST</div>
</div>
If you just want to use css, just use:
.content:hover {
margin-top: -50px;
height: 110%;
}
See jsFiddle
since there isn't any space at top to expand, you may give an extra margin initially and remove it on hover like this JsFiddle -
.box {
height: 170px;
padding-bottom: 15px;
width: 50%;
}
.content {
background-color: #e3e4e6;
height: 100%;
text-align: center;
margin-top:25px;
}
.content:hover {
height: 110%;
margin-top:0;
}
Set top property with the value of height - 100 * -1
https://jsfiddle.net/x3cL1cpt/7/
.content:hover {
height: 110%;
top: -10%;
position: relative;
}
Why position relative? It's because I move the box, but without modifying the space that the box occuped. If you need to modify that space, change top with margin-top.
Replace this CSS with your current, needed to add transition:
.box {
height: 170px;
padding-bottom: 15px;
width: 50%;
}
.content {
background-color: #e3e4e6;
height: 100%;
text-align: center;
transition: 1s all ease;
}
.content:hover {
transform: scaleY(1.2);
transform-origin: bottom right;
}
So I'm trying to get a div to fade in when a scroll threshold has been reached. It starts off with display: none; in the css for its div id. When the threshold is hit, fadein does not remove display:none; from the css as I've read it should.
CSS:
#SideBanner01{
display: none;
right: 0;
margin-left: 60.4%;
margin-right: 3%;
margin-top: .25%;
overflow: hidden;
}
#SideBanner01 img{
width: 206.25%;
margin: -30% -15% -8% -140%;
}
Javascript:
$(window).scroll(function () {
var delay = 500;
var scrollTop = $(window).scrollTop();
if (scrollTop > 20) {
$('#SideBanner01').fadeIn(delay);
}
else{
$('#SideBanner01').hide();
}
});
Inspector after fadein runs:
element {
position: fixed;
}
#SideBanner01 {
display: none;
right: 0;
margin-left: 60.4%;
margin-right: 3%;
margin-top: .25%;
overflow: hidden;
}
body {
color: #000000;
text-align: left;
}
Html:
<div style="position: fixed;" id="SideBanner01"><img src="http://survey.unifocus.com/ClientFiles/19500/Bardessono-stone-wheels.jpg"></div>
I'm using jquery 1.6 so I believe fadein should work as I'm trying it. Any idea on what is going on? I've been able to get "$('#SideBanner01').show(delay);" to work but it flies in from the side but it looks pretty tacky. Thanks in advance.
Don't you mean to do:
$(window).scroll(function () {
var delay = 500;
if ($(this).scrollTop() > 20) {
$('#SideBanner01').fadeIn(delay);
}
else{
$('#SideBanner01').hide();
}
});
In your code snippet, scrollTop is used as a regular variable (not defined).