What is the best way to make a div scroll along with the page?
The exact effect is utilized # http://store.apple.com/ (on the checkout summary after a product is added to the cart)
edit: or this example - alas, it's not as smooth as i'd like it to be =/
In the second example, they are using jQuery to do this. Scroll event of window object is caught and the using the animate() function the position of div is changed dynamically.
This tutorial should help you: http://css-tricks.com/scrollfollow-sidebar/
jQuery saves the day... again!
CSS:
#wrapper {
position: absolute;
width: 200px;
}
#fancyDiv {
position: absolute;
top: 0;
}
#fancyDivt.fixed {
position: fixed;
top: 0;
}
html:
<div id="commentWrapper">
<div id="comment">
<p>some text</p>
</div>
</div>
jQuery:
$(document).ready(function() {
$(function () {
var top = $('#fancyDiv').offset().top - parseFloat($('#fancyDiv').css('margin-top').replace(/auto/, 0));
$(window).scroll(function (event) {
// what the y position of the scroll is
var y = $(this).scrollTop();
// whether that's below the div
if (y >= top) {
// if so, ad the fixed class
$('#fancyDiv').addClass('fixed');
} else {
// otherwise remove it
$('#fancyDiv').removeClass('fixed');
}
});
}
});
Related
I'm trying to make fixed navigation bar with modifying Bootstrap CSS file. If I scroll down, navbar's color should be changed and fixed to the top.
So I've added following JS code by referring to this article but it doesn't work.
let MQL = 992;
if ($(window).width() > MQL) {
let headerHeight = $("#mainNav").height();
$(window).scroll(function () {
if ($(document).scrollTop() > headerHeight) {
$("#mainNav").addClass("is-visible");
} else {
$("#mainNav").removeClass("is-visible");
}
});
}
#mainnav is CSS for navigation bar, and is-visible is CSS animation for displaying navbar. 992 is mininum width for desktop screen.
JSFIDDLE
How to I solve this?
Please check the working solution here.
var headerHeight = $(".clearHeader").height();
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= headerHeight) {
$(".clearHeader").addClass("is-visible");
}else{
$(".clearHeader").removeClass("is-visible");
}
});
.clearHeader{
height: 200px;
background-color: rgba(107,107,107,0.66);
position: fixed;
top:200;
width: 100%;
}
.is-visible {height: 100px;background-color:#1e1e1e}
.wrapper {
height:2000px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header class="clearHeader">
</header>
<div class="wrapper">
</div>
I wan't to make a special menu for the iPad version of my website.
It should work like this:
http://itu.dk/people/mbul/humlum/images/ipad_menu.png
Click on IMG 1 and the menu expands (to IMG 2) and the links gets visible. When you click outside IMG 2 it disappears along with the links so only IMG 1 is visible.
I've come this far but it doesn't really do the trick:
<div class="nav_mobile_container">
<div class="nav_mobile_elements">
<div class="nav_mobile"></div>
</div>
</div>
div.nav_mobile_container{
position: fixed;
top: 0px;
left: 0px;
}
div.nav_mobile_elements{
display: inline-block;
}
div.nav_mobile_elements a{
vertical-align: top;
display: inline-block;}
div.nav_bookmark:hover{
display: inline-block;
}
.nav_mobile{
width:70px;
height:70px;
background-image:url('images/menu_small.png');
display: inline-block;
}
.nav_mobile:hover{
width:496px;
height:500px;
background-image:url('images/menu_small_expanded.png');
}
I would really appreciate a CSS solution on this if possible.
Thank you!
The closest you can get is
#nav_mobile:active {
width:496px;
height:500px;
background-image:url('images/menu_small_expanded.png');
}
But that does not work on an ipad.
I recommend to use a bit of javascript.
Create an onclick event that displays a div with all the navigation information you need.
With jquery:
$("#small_navigation").click(function(){
$("#big_navigation").show();
});
The css:
#big_navigation {
display: none;
width: ...
height: ...
etc...
}
You will need javascript for this. Using jQuery, this is how you could make it :
First, don't set an :hover in your CSS, but just make a class that you will add on click :
.nav_mobile.navopen {
width:496px;
height:500px;
background-image:url('images/menu_small_expanded.png');
}
And then a bit of jQuery to make it work :
$(document).ready(function(){
// expend the menu on click
$('.nav_mobile').on('click', function(event){
event.stopPropagation();
$(this).addClass('navopen');
});
// close menu on click outside the menu
$('html').click(function() {
$('.nav_mobile').removeClass('navopen');
});
});
The jsFiddle demo
Edit : with pure javascript
window.onload = function() {
var menu = document.getElementsByClassName('nav_mobile')[0];
menu.onclick=function(e){
e.stopPropagation();
menu.className = "nav_mobile navopen";
};
var html = document.getElementsByTagName('html')[0];
html.onclick=function(){
menu.className = "nav_mobile";
};
};
I am working on a webpage using jQuery Mobile, iScrollview, and Google Maps. When the map gets initialized, it will load a set of markers with infowindows containing an image. When the image gets clicked, it will load the content of a jQM popup with a list and show the popup.
I am having 2 problems:
1) How can I set a height (e.g. 150px) for my jQM popup's content? Using iScrollview, the content's height becomes overridden and becomes large. Using the refresh() as specified in the documentation has no effect (or am I using it wrong?).
2) Is there a way for me to show a scrollbar only if the list exceeds the height of the content? Currently, it always shows a scrollbar.
HTML
<div style="display: none;">
<div class="popup">
<div class="header" data-role="header">
<h1>Products</h1>
</div>
<div class="content" data-role="content" data-iscroll>
</div>
<div class="footer" data-role="footer">
<a class="close" href="#" data-rel="back" data-role="button">Close</a>
</div>
</div>
</div>
CSS
.popup {
width: 175px;
}
.popup .content {
height: 150px; /* has no effect */
padding: 10px;
}
.popup .content ul {
list-style-type: none;
margin: 0px;
padding: 0px;
}
.popup .content ul li {
height: 23px;
line-height: 23px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
JavaScript
var markers = [];
function addMarker(i, retailer) {
var marker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(retailer.lat, retailer.lng),
products: retailer.products // array of strings of unknown length
});
var infobox = new InfoBox({
boxClass: 'infobox',
closeBoxURL: '',
content: '\
<img class="detail" src="img/arrow_light.png" alt="" onclick="openPopup('+ parseInt(i) +');" />\
<div class="name"><span>' + retailer.name + '</span></div>\
<div class="address"><span>' + retailer.address + '</span></div>\
<div class="arrow"></div>',
maxWidth: 500,
pixelOffset: new google.maps.Size(0, -110)
});
markers.push(marker);
}
function openPopup(i) {
var items = [];
// create list
$.each(markers[i].products, function(i, name) {
items.push('<li>' + name + '</li>');
});
// set popup's content
$('.popup .content')
.empty()
.append('<ul class="list">' + items.join('') + '</ul>')
.iscrollview('refresh');
// show popup
$('.popup').popup({ history: false, transition: 'pop' }).popup('open');
}
Only thing you need to do is override popup content height and inforce it like this:
.ui-popup .ui-content {
height: 150px !important;
}
Remember to use !important if you want to override class css. !important is only needed when working with classes. For example if you initialize your css through id (#) !important is not needed.
Working example: http://jsfiddle.net/Gajotres/N28Vg/
The bootstrap documentation on that topic is a little confusing to me. I want to achieve similar behaviour like in the docs with the affix navbar: The navbar is below a paragraph / page heading, and upon scrolling down it should first scroll along until reaching the top of the page, and then stick there fixed for further scrolldowns.
As jsFiddle does not work with the navbar concept, I've set up a separate page for usage as a minimal example: http://i08fs1.ira.uka.de/~s_drr/navbar.html
I use this as my navbar:
<div class="navbar affix-top" data-spy="affix" data-offset-top="50">
<div class="navbar-inner">
<div class="container">
<div class="span12">
<a class="brand" href="#">My Brand</a>
This is my navbar.
</div>
</div> <!-- container -->
</div> <!-- navbar-inner -->
</div> <!-- navbar -->
I thinkg i would want data-offset-top to be of value 0 (since the bar should "stick" to the very top" but with 50 there is at least some effect watchable.
If also put the javascript code in place:
<script>
$(document).ready (function (){
$(".navbar").affix ();
});
</script>
Any help appreciated.
I was having a similar problem, and I believe I found an improved solution.
Don't bother specifying data-offset-top in your HTML. Instead, specify it when you call .affix():
$('#nav').affix({
offset: { top: $('#nav').offset().top }
});
The advantage here is that you can change the layout of your site without needing to update the data-offset-top attribute. Since this uses the actual computed position of the element, it also prevents inconsistencies with browsers that render the element at a slightly different position.
You will still need to clamp the element to the top with CSS. Furthermore, I had to set width: 100% on the nav element since .nav elements with position: fixed misbehave for some reason:
#nav.affix {
position: fixed;
top: 0px;
width: 100%;
}
One last thing: When an affixed element becomes fixed, its element no longer takes up space on the page, resulting in the elements below it to "jump". To prevent this ugliness, I wrap the navbar in a div whose height I set to be equal to the navbar at runtime:
<div id="nav-wrapper">
<div id="nav" class="navbar">
<!-- ... -->
</div>
</div>
.
$('#nav-wrapper').height($("#nav").height());
Here's the obligatory jsFiddle to see it in action.
Just implemented this for the first time, and here's what I've found.
The data-offset-top value is the amount of pixels that you must scroll in order for the affixing effect to take place. In your case, once 50px is scrolled, the class on your item is changed from .affix-top to .affix. You'd probably want to set data-offset-top to about 130px in your use case.
Once this class change occurs, you must position your element in css by styling the positioning for class .affix. Bootstrap 2.1 already defines .affix as position: fixed; so all you need to do is add your own position values.
Example:
.affix {
position: fixed;
top: 20px;
left: 0px;
}
To fix this very issue I have modified the affix plugin to emit a jQuery event when an object is affixed or unaffixed.
Here is the pull request: https://github.com/twitter/bootstrap/pull/4712
And the code: https://github.com/corbinu/bootstrap/blob/master/js/bootstrap-affix.js
And then do this to attach the navbar:
<script type="text/javascript">
$(function(){
$('#navbar').on('affixed', function () {
$('#navbar').addClass('navbar-fixed-top')
});
$('#navbar').on('unaffixed', function () {
$('#navbar').removeClass('navbar-fixed-top')
});
});
</script>
You need to remove .affix() from your script.
Bootstrap gives the option of accomplishing things either via data-attributes or straight JavaScript most of the time.
I've got this from the twitterbootstrap's source code and it's working pretty well:
HTML:
<div class="row">
<div class="span3 bs-docs-sidebar">
<ul id="navbar" class="nav nav-list bs-docs-sidenav">
...
</ul>
</div>
</div>
CSS:
.bs-docs-sidenav {
max-height: 340px;
overflow-y: scroll;
}
.affix {
position: fixed;
top: 50px;
width: 240px;
}
JS:
$(document).ready(function(){
var $window = $(window);
setTimeout(function () {
$('.bs-docs-sidenav').affix({
offset: {
top: function (){
return $window.width() <= 980 ? 290 : 210
}
}
})
}, 100);
});
You just need to remove the script. Here is my example:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.0.min.js"></script>
<script type="text/javascript" src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.1.0/js/bootstrap.min.js"></script>
<style>
#content {
width: 800px;
height: 2000px;
background: #f5f5f5;
margin: 0 auto;
}
.menu {
background: #ccc;
width: 200px;
height: 400px;
float: left;
}
.affix {
position: fixed;
top: 20px;
left: auto;
right: auto;
}
</style>
</head>
<body>
<div id="content">
<div style="height: 200px"></div>
<div class="affix-top" data-spy="affix" data-offset-top="180">
<div class="menu">AFFIX BAR</div>
</div>
</div>
</body>
</html>
Thanks to namuol and Dave Kiss for the solution.
In my case I had a tiny problem with navbar height and width when I used afflix and collapse plugins together. The problem with width can be easily solved inheriting it from parent element (container in my case). Also I could manage to make it collapsing smoothly with a bit of javascript (coffeescript actually). The trick is to set wrapper height to auto before collapse toggle occurs and fix it back after.
Markup (haml):
#wrapper
#navbar.navbar
.navbar-inner
%a.btn.btn-navbar.btn-collapse
%span.icon-bar
%span.icon-bar
%span.icon-bar
#menu.nav-collapse
-# Menu goes here
CSS:
#wrapper {
width: inherit;
}
#navbar {
&.affix {
top: 0;
width: inherit;
}
}
Coffeescript:
class Navigation
#initialize: ->
#navbar = $('#navbar')
#menu = $('#menu')
#wrapper = $('#wrapper')
#navbar.affix({offset: #navbar.position()})
#adjustWrapperHeight(#navbar.height())
#navbar.find('a.btn-collapse').on 'click', () => #collapse()
#menu.on 'shown', () => #adjustWrapperHeight(#navbar.height())
#menu.on 'hidden', () => #adjustWrapperHeight(#navbar.height())
#collapse: ->
#adjustWrapperHeight("auto")
#menu.collapse('toggle')
#adjustWrapperHeight: (height) ->
#wrapper.css("height", height)
$ ->
Navigation.initialize()
My solution for attach the navbar :
function affixnolag(){
$navbar = $('#navbar');
if($navbar.length < 1)
return false;
h_obj = $navbar.height();
$navbar
.on('affixed', function(){
$navbar.after('<div id="nvfix_tmp" style="height:'+h_obj+'px">');
})
.on('unaffixed', function(){
if($('#nvfix_tmp').length > 0)
$('#nvfix_tmp').remove();
});
}
Similar to the accepted answer, you can also do something like the following to do everything in one go:
$('#nav').affix({
offset: { top: $('#nav').offset().top }
}).wrap(function() {
return $('<div></div>', {
height: $(this).outerHeight()
});
});
This not only invokes the affix plugin, but will also wrap the affixed element in a div which will maintian the original height of the navbar.
I have a div that I'd like to have a vertical scrollbar.
So far, I have used the following css, which works fine:
.mywrapper {
max-height: 300px;
overflow: auto;
}
However, I would like the div to take up as much vertical space on the page as possible. Since this is the last div on the page, I'd like it to extend all the way down to the bottom, if possible.
You can't do this, naturally. The body only goes as high as the content it contains.
But, a simple quick fix would be adding this to your CSS:
html,body { height: 100%; margin: 0; padding: 0; }
As for extending, I've put together a quick script (using jQuery) that appears to do what you're looking for.
Please see: http://jsfiddle.net/UB7uT/ (click Play)
Code:
CSS:
html,body { height: 100%; margin: 0; padding: 0; overflow: hidden; }
.mywrapper {
overflow: auto;
max-height: 100%;
}
JavaScript:
function my_initialize_footer_box_absolute_height_scroller(selector) {
var box = $(selector);
var boxPosition = box.position();
var boxTop = boxPosition.top;
var boxHeight = box.height();
var boxNewHeight = (+boxHeight) - (+boxTop);
box.css('height', boxNewHeight+'px');
}
$(function() {
my_initialize_footer_box_absolute_height_scroller('.mywrapper');
});
HTML:
<p>some content here first.</p>
<p>some content here first.</p>
<p>some content here first.</p>
<p>some content here first.</p>
<hr>
<div class="mywrapper">
foo<br>foo<br>foo<br>foo<br>foo<br>foo<br>foo<br>foo<br>
</div>