I need to quickly knock up the functionality of the twitter bootstraps main navigation and sub navigation e.g. http://twitter.github.com/bootstrap/scaffolding.html (when you scroll the subnav becomes fixed to that main navigation)
Has anyone implemented this or are there any tutorials?
Here is my code to implement this feature:
$(document).scroll(function(){
// If has not activated (has no attribute "data-top"
if (!$('.subnav').attr('data-top')) {
// If already fixed, then do nothing
if ($('.subnav').hasClass('subnav-fixed')) return;
// Remember top position
var offset = $('.subnav').offset()
$('.subnav').attr('data-top', offset.top);
}
if ($('.subnav').attr('data-top') - $('.subnav').outerHeight() <= $(this).scrollTop())
$('.subnav').addClass('subnav-fixed');
else
$('.subnav').removeClass('subnav-fixed');
});
As of 2012-12-04 the accepted answer is no longer the best choise, since the desired functionality has been included into Bootstrap.
Please see Affix JavaScript component which is part of Bootstrap JS
Great Answer from #Oleg,
For people like me who want to reproduce the responsive behaviour of the .subnav
Here is the css code (without colors, borders and effects)
body { padding-top: 90px; }
#media (max-width: 980px) {
body {
padding-top: 0;
}
}
.subnav {
width: 100%;
}
#media (max-width: 768px) {
.subnav {
position: static;
top: auto;
z-index: auto;
width: auto;
height: auto;
}
.subnav .nav > li {
float: none;
}
}
#media (min-width: 980px) {
.subnav-fixed {
position: fixed;
top: 40px;
left: 0;
right: 0;
z-index: 1020;
}
.subnav-fixed .nav {
width: 938px;
margin: 0 auto;
}
}
#media (min-width: 1210px) {
.subnav-fixed .nav {
width: 1168px;
}
}
If you want to clone the style of the menu (including colors, borders and effects)
http://jsfiddle.net/baptme/ydY6W/
The two answers above work great, but I just thought I'd let people know that I've made this into a module (without the jQuery dependency) available at ForbesLindesay/booting-sub-nav. It can be used standalone with a script tag or via https://github.com/component/component/
Here is another code
$(function(){
var
$win = $(window),
$filter = $('.navbar'),
$filterSpacer = $('<div />', {
"class": "filter-drop-spacer",
"height": $filter.outerHeight()
});
$win.scroll(function(){
if(!$filter.hasClass('navbar-fixed-top')){
if($win.scrollTop() > $filter.offset().top){
$filter.before($filterSpacer);
$filter.addClass("navbar-fixed-top");
}
}else if ($filter.hasClass('navbar-fixed-top')){
if($win.scrollTop() < $filterSpacer.offset().top){
$filter.removeClass("navbar-fixed-top");
$filterSpacer.remove();
}
}
});
});
Related
When a user's browser has a width of less than 1160px, a media query is setup to collapse my site's right sidebar. They can get it back by clicking on a little arrow and then it will overlap the content (absolute positioning).
Anyway, I used the following jQuery to achieve this:
$('.right_sidebar_preview').on('click', function() {
$('.right_sidebar_preview').css('display', 'none');
$('.right_sidebar').css('display', 'block');
});
$('.right_sidebar').on('click', function() {
$('.right_sidebar_preview').css('display', 'block');
$('.right_sidebar').css('display', 'none');
});
So basically I already have the preview hidden when the browser is larger than 1160px and the sidebar is visible, in the media query I have it set up so when it's below 1160px, the sidebar becomes invisible and the "sidebar preview" is shown which users can click to make it bigger.
CSS:
.right_sidebar {
width: 242px;
height: 100%;
background-color: #d8e1ef;
float: right;
position: relative;
}
.right_sidebar_preview {
display: none;
}
#media(max-width:1160px) {
.right_sidebar {
position: absolute;
right: 0;
display: none;
}
.right_sidebar_preview {
display: block;
background-color: #d8e1ef;
position: absolute;
right: 0;
width: 15px;
height: 100%;
}
}
My question is, when I use the code above, let's say we're in the less than 1160px media query, I'll open the sidebar then collapse it again, and when I stretch my browser out to go back, it also closed the sidebar on the greater than 1160px media query.
So is there anyway I can use .css() (or an alternative method) to point at a specific media query?
Do not manipulate the CSS display: property. Instead, use CSS classes to control the visibility of sidebar and its handle. This way you can use your media query to control whether an element displays or not.
In the following demo, click the "Full page" button to see how this works on screens > 1160px.
$(function() {
$('.right_sidebar, .right_preview').on('click', function() {
$('.right_sidebar, .right_preview').toggleClass('lt-1160-hide lt-1160-show');
});
});
.right_sidebar {
width: 100px;
height: 100px;
background-color: papayawhip;
float: left;
display: block;
}
.right_preview {
width: 20px;
height: 100px;
background-color: palegoldenrod;
float: left;
display: none;
}
#media(max-width: 1160px) {
/* note: the following rules do not apply on larger screens */
.right_sidebar.lt-1160-show, .right_preview.lt-1160-show {
display: block;
}
.right_sidebar.lt-1160-hide, .right_preview.lt-1160-hide {
display: none;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="right_sidebar lt-1160-hide">Sidebar</div>
<div class="right_preview lt-1160-show">›</div>
On a recent project, I had to process a single function in jQuery based on the browser size. Initially I was going to check the device width was applicable to a mobile device (320px):
jQuery
$(window).resize(function(){
if ($(window).width() <= 320) {
// your code here
}
});
or
$(window).resize(function(){
if ($('header').width() == 320 ){
// your code here
}
});
Something like this?
$(window).resize(function(){
if ($(window).width() <= 1160){
// lets party
}
});
I have an element with image and text,
Fiddle. Note: Resize preview enough to make grid big enough.
Here is my CSS:
.gridster .gs-w .item{
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
}
.gridster .gs-w .item .obj{
background-color: #00A9EC;
}
.gridster .gs-w .item .itemIcon {
height: 100%;
width: 100%;
float:left;
overflow: hidden;
z-index: 10;
}
.gridster .gs-w .item .itemIcon {
background-image: url(http://icons.iconarchive.com/icons/dakirby309/windows-8-metro/256/Apps-Calendar-Metro-icon.png);
background-repeat:no-repeat;
background-size:contain;
align-content: center;
}
.gridster .gs-w .item .itemText{
display: block;
width: 100%;
position: relative;
margin-right: 0px;
right: 0px;
text-align: right;
z-index: 9;
}
.gridster .gs-w .item .itemText a{
vertical-align: center;
text-align:right;
color:white;
padding-right: 10%;
font-size: 14px;
font-weight: 600;
text-decoration:none;
font-family: 'Segoe UI';
}
I want to show text when element is expanded, and hide when element is collapsed, I think I can achieve it by CSS, but it's not yet clear what is wrong.
and here it is collapsed
advise some CSS code, in case if possible to make in CSS.
You can hook into resize.resize.
By checking data attribute data-sizex you get how many columns the cell spans. By this you can expand the init function to the following:
Sample fiddle.
public.init = function (elem) {
container = elem;
// Initialize gridster and get API reference.
gridster = $(SELECTOR, elem).gridster({
shift_larger_widgets_down: true,
resize: {
enabled: true,
resize: function (e, ui, $widget) {
var cap = $widget.find('.itemText');
// Hide itemText if cell-span is 1
if ($widget.attr('data-sizex') == 1) {
cap.hide();
} else {
cap.show();
}
}
}
}).data('gridster');
hookWidgetResizer();
}
Or cleaner, and likely preferable. Split it out to own function and say something like:
resize: capHide
Sample fiddle.
If you rather go for the solution proposed by your updated images, one way is to tweak the CSS on resize, using your resize_widget_dimensions function. Sure this can be done better, but as a starter you can have this:
Sample fiddle.
this.$widgets.each($.proxy(function (i, widget) {
var $widget = $(widget);
var data = serializedGrid[i];
this.resize_widget($widget, data.size_x, data.size_y);
// Find itemText
var $it = $widget.find('.itemText');
// Set CSS values.
$it.css({width:this.min_widget_width, left:this.min_widget_width});
}, this));
Challenge is that the gridster is a very fluid cake where a lot of the dimensions and positioning is done by JavaScript rather then pure CSS. Anyhow, the above should give a direction on how to tweak it, and might even be good enough ;)
As a final treat you can resize the font according to cell size. I'm not sure how to best find the size you want as you divide the space between icon/image and text. But something like this:
Sample fiddle.
Where you have a hidden span to measure text:
<span id="font_sizer"></span>
With CSS:
#font_sizer {
position: absolute;
font-family:'Segoe UI';
visibility: hidden;
}
And font measure by:
function szFont(w, t) {
var s = 1, $fz = $('#font_sizer');
$fz.text(t);
$fz.css('fontSize', s + 'px');
while ($fz.width() < w - 2)
$fz.css('fontSize', ++s + 'px');
return s;
}
You can set font size as:
var fontSize = szFont(this.min_widget_width - 10, 'Objects');
Where this.min_widget_width - 10 is the part where you set size available for text. Then you can say:
var $it = $widget.find('.itemText');
$it.css({fontSize: fontSize + 'px', width:this.min_widget_width, left:this.min_widget_width});
Other notes:
You have a typo in:
var container,
grister, // <<-- Missing 'd' in gridster
resizeTimer;
In extensions you have
var data = serializedGrid[i];
this.resize_widget($widget, data.sizex, data.sizey);
however a console.log of data show:
data.size_x
data.size_y
not sure how this fits in. The data attribute uses sizex / y but data property from serialize, (on object), it uses size_x / y with underscore.
I think you are looking for media query:
#media all and (max-width: 760px) {
.gridster .gs-w .item .itemText {
display: none;
}
}
Example
You can hide text by using below type of CSS
.gridster .gs-w .item .itemText a.hide-text {
text-align: left;
text-indent: -99999px;
display: inline-block;
}
now whenever you want to hide text you need to add this class i.e. hide-text on anchor element Objects and vice versa to show text remove class
basically you need to try and figure out best possible solution to fit all requirements Good luck
I am attempting to create a navigation bar that remains fixed only after it has reached the top of the page. I have the code working so that the nav is fixed, but I can't seem to get it to scroll to the top first.
Here's the HTML:
<div id= "home"> contentcontentcontent </div>
<div id="nav">
home
go green
your area
how to</div>
And the CSS:
nav {
text-align: center;
top: 600;
z-index: 100;
position: fixed;
width: 100%;
border: 0;
margin-bottom: 0;}
fixed {
top:600;
z-index: 100;
position: fixed;
width: 100%;}
home {
overflow: hidden;}
And the jQuery:
$(document).ready(function() {
$(window).scroll(function () {
//console log determines when nav is fixed
console.log($(window).scrollTop())
if ($(window).scrollTop() > 600) {
$('#nav').addClass('fixed');
}
if ($(window).scrollTop() < 601) {
$('#nav').removeClass('fixed');
}
});
These were based off of responses to similar questions on this site, but nothing has seemed to work so far. Does anyone know what's wrong with my code?
When writing a CSS selector, ids and classes need to be prefixed by a # or a . respectively. In your CSS you have
nav { // rules }
fixed { // rules }
home { // rules }
When you should have
#nav { // rules }
.fixed { // rules }
#home { // rules }
Here is a fiddle of your code working.
I am developing a site and I want to make a script that will detect when the page is more than 500px and when it is below so I can make changes to the code. My current code has some links at the end of the page, like a footer, and when it is below 500px I want them to come close to each other for example;
<div class="footer-titles">
<ul class="footer-titles-ul">
<li><h class="titles">Link 1</h></li>
<li><h class="titles">Link 2</h></li>
<li><h class="titles">Link 3</h></li>
</ul>
</div>
And my css
.footer-titles{width: auto; min-width: 800px; left: 0px; right: 0px; position: absolute; bottom: 210px;}
.footer-titles-ul {list-style: none; padding-left: 120px;}
.footer-titles-ul li {padding-right: 90px; display: inline;}
So when the page is below 500px I want the padding-right from the .footer-titles-ul li to be 30px but, if the page gets back to over 500px to revert back to normal.
You don't need JavaScript for this and you shouldn't use JavaScript for this. You want CSS3 Media Queries (Unless you need old browser support that's not possible with a polyfill).
You would want something like this to get the change:
#media screen and (max-width: 500px) {
/* UNDER 500px CSS here */
.class{
color: red;
}
}
Using media queries is the way to go. Just add this to the bottom of your CSS file:
#media only screen and (max-width: 500px) {
.footer-titles-ul {padding-right: 30px;}
}
If you want jQuery, I think this would work for you. But then again, I would recommend CSS media queries as the others say.
$(document).ready(function(){
var detectViewPort = function() {
var Wwidth = $(window).width();
if (Wwidth < 500){
$('.footer-titles-ul li').css('padding-right', '30px');
}
if (Wwidth > 500){
$('.footer-titles-ul li').css('padding-right', '90px');
}
};
$(function(){
detectViewPort();
});
$(window).resize(function () {
detectViewPort();
});
});
I've a sticked element which gets the top-alignment from current scroll-offset. Problem is, that the layout is not "retriggerd" if the space from it is free. So there stays a ghost-gap where the sticked element was...
http://fiddle.jshell.net/pPc4V/
The markup is pretty simple:
...
as well as the js:
var $win = $(this);
var sticked = document.querySelector('a.sticked');
$win.on('scroll', function () {
var scrollTop = $win.scrollTop();
sticked.style.top = scrollTop + 'px';
// $win.resize();
});
...and the css looks good so far:
a {
display: inline-block;
width: 90px;
height: 90px;
background: deepskyblue;
}
.sticked {
position: relative;
top: 0;
left: 0;
background: tomato;
}
I tried to trigger the resize-event on scroll (as you see above uncommented), but no success! Any ideas, how to retrigger the layout so that the free-gap is filled with the next floated element?
Update
To clarify what I mean I made a simple image-timelime:
Step 1
Step 2
Step 3
The issue is that you are setting position fixed on an element which is displayed inline. That will cause that space to occur. I have redid your jsFiddle with proper alignment.
To fix it, I added the class "stuck" only when the document's scrollTop position is greater than the scrollTop position of your target element.
jsFiddle: http://fiddle.jshell.net/pPc4V/44/
HMTL:
<div id="grid">
etc...
</div>
CSS:
#grid {
height:1000px;
overflow:hidden;
float:left
}
#grid > a {
display: inline-block;
width: 90px;
height: 90px;
background: deepskyblue;
}
.stuck {
position: fixed;
background: navy !important;
}
JS:
$(window).on('scroll', function () {
var $doc = $(document),
parentElement = $('#grid'),
childToGetStuck = parentElement.find('a:nth-child(5)');
if ($doc.scrollTop() > childToGetStuck.scrollTop()) {
childToGetStuck.addClass('stuck');
//console.log($('.stuck').scrollTop())
} else {
childToGetStuck.removeClass('stuck');
}
});