Responsive Horizontal Scrolling Menu
Solution 1
So, finally I think I have what you are looking for:
Fiddle: http://jsfiddle.net/fzXMg/2/
CSS and HTML is in the Fiddle...
JS:
$(function(){
var state = 0;
var maxState = 6;
var winWidth = $(window).width();
$(window).resize(function(){
winWidth = $(window).width();
$('.box,.container_element').width(winWidth-100);
}).trigger('resize');
$('#lefty').click(function(){
if (state==0) {
state = maxState;
} else {
state--;
}
$('.container_element').animate({scrollLeft:((winWidth-100)*state)+'px'}, 800);
});
$('#righty').click(function(){
if (state==maxState) {
state = 0;
} else {
state++;
}
$('.container_element').animate({scrollLeft:((winWidth-100)*state)+'px'}, 800);
});
});
This uses jQuery again.
Solution 2
Now that the healthunit site has changed the original question is not completely clear.
To make a nav menu that scrolls horizontally uses arrow buttons (instead of scrollbar) can be implemented with a little jQuery and easily converted to pure JavaScript.
var $bar = $('.nav');
var $container = $('#outer');
var widths = {};
var scrollOffset = 0;
var container = document.getElementById("outer");
var bar = document.getElementById("bar");
function setMetrics() {
metrics = {
bar: bar.scrollWidth||0,
container: container.clientWidth||0,
left: parseInt(bar.offsetLeft),
getHidden() {
return (this.bar+this.left)-this.container
}
}
updateArrows();
}
function doSlide(direction){
setMetrics();
var pos = metrics.left;
if (direction==="right") {
amountToScroll = -(Math.abs(pos) + Math.min(metrics.getHidden(), metrics.container));
}
else {
amountToScroll = Math.min(0, (metrics.container + pos));
}
$bar.css("left", amountToScroll);
setTimeout(function(){
setMetrics();
},400)
}
function updateArrows() {
if (metrics.getHidden() === 0) {
$(".toggleRight").addClass("text-light");
}
else {
$(".toggleRight").removeClass("text-light");
}
if (metrics.left === 0) {
$(".toggleLeft").addClass("text-light");
}
else {
$(".toggleLeft").removeClass("text-light");
}
}
function adjust(){
$bar.css("left", 0);
setMetrics();
}
$(".toggleRight").click(function(){
doSlide("right");
});
$(".toggleLeft").click(function(){
doSlide("left");
});
$(window).on("resize",function(){
// reset to left pos 0 on window resize
adjust();
});
setMetrics();
Demo: https://www.codeply.com/go/HgAVBVfQFY
Solution 3
Check out that fiddle: http://jsfiddle.net/zEPQ5/15/
It's not perfect in meaning of design, but it shows off the concept.
I used jQuery with that.
$(function(){
var state = 0;
$('#up').click(function(){
state += 1;
$('ul.wrapper').animate({marginTop:(15-state*35)+'px'},400);
});
$('#down').click(function(){
state -= 1;
$('ul.wrapper').animate({marginTop:(15-state*35)+'px'},400);
});
});
Comments
-
Huginn over 4 years
http://healthunit.com has a clean horizontal scrolling menu at the top of the screen once you view it from a mobile phone device. I'm trying to mimic that same exact functionality thanks to a site I'm redesigning with a huge level of navigation elements.
Requirements:
- Left and right scroll click options
- Centered list item option centered in the space
- Only one list item visible at a time
- Horizontal Scrolling & Responsive
- Clicking the last or first option in the list will take you to either the first option or last option in the list
My current html for this section is:
<nav id="sub" class="clearfix"> <ul class="wrapper"> <a href="#"><li>Estimate</li></a> <a href="#"><li>About</li></a> <a href="#"><li>Customer Information</li></a> <a href="#"><li>Financing</li></a> <a href="#"><li>Careers</li></a> <a href="#"><li>Locate Us</li></a> <a href="#"><li>Inspiration</li></a> </ul> </nav>
The CSS currently attached to it is:
nav#sub { background: #004173; background: linear-gradient(to bottom, #004173 0%,#014f8d 100%); background: -moz-linear-gradient(top, #004173 0%, #014f8d 100%); background: -ms-linear-gradient(top, #004173 0%,#014f8d 100%); background: -o-linear-gradient(top, #004173 0%,#014f8d 100%); background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#004173), color-stop(100%,#014f8d)); background: -webkit-linear-gradient(top, #004173 0%,#014f8d 100%); border-bottom: #00325a solid 3px; box-shadow: 0 4px 6px 0 #BFBFBF; filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#004173', endColorstr='#014f8d',GradientType=0 ); webkit-box-shadow: 0 4px 6px 0 #BFBFBF; } #sub ul { text-align: center; } #sub ul li { padding: 10px 3.3%; } #sub a { color: #fff; font-size: 10pt; font-weight: 400; text-decoration: none; } #sub ul a:hover li { background: #007FEB; }
-
Huginn almost 10 yearsDefinitely heading in the right direction, the main differences I think that I see between the example and yours is that yours is scrolling vertically opposed to horizontally, and that you can go past your first and last option without returning to the top or end of the list. I'll edit the requirements to include the last part. Nice work so far though, you definitely got the idea.
-
Huginn almost 10 yearsExactly it! very nice Stefan. +1 Badass Token to your coding skills.
-
Harsha over 9 yearsWow it's a best answer. +1
-
Francisco Corrales Morales almost 9 yearswhat if I want more than 1 item to be show at a time ? something like
< item1 item2 item3 >
, like split in 4, and every time the user hits <, > it moves a shift to the side.