-
-
Save aasutossh/f1423ba1b8e66b1d25bf7a08336e8e79 to your computer and use it in GitHub Desktop.
Setting scroll to center on an element (jQuery) - Super simple stuff
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
If you have a horizontal (or vertical) scroll container and want to set the scroll to center a specific | |
element in the container you can use the following super simple technique. | |
I'm going to show you how it was derived, because it's important to know why, not just how. | |
*/ | |
/* | |
Setup: | |
[HTML] | |
<div class="outer"> | |
<div> | |
<ul> | |
<li>Alpha</li><li>Beta</li>...<li>Omega</li> | |
</ul> | |
</div> | |
</div> | |
[CSS] | |
div.outer { | |
width: 400px; height: 100px; overflow-x: auto; overflow-y: hidden; | |
} | |
div.outer > div { | |
display: table; | |
} | |
ul { | |
display: table-row; | |
} | |
li { | |
display: table-cell; width: 120px; height: 120px; border: 2px solid gray; | |
} | |
*/ | |
/* | |
With this setup, we should have a nice horizontally scrolling list of items of all the same width. | |
|--DIV.outer---------------------------------| { Hidden Elements } | |
||--DIV-and UL------------------------------|/....................................| | |
|||---LI---||---LI---||---LI---||---LI---||-//LI...||...LI...||...LI...||...LI...|| | |
||| || || || || // || || || || | |
||| || || || || // || || || || | |
|||--------||--------||--------||--------||-//.....||........||........||........|| | |
||------------------------------------------|/....................................| | |
|--------------------------------------------| | |
*/ | |
/* | |
jQuery provides a function, scrollLeft (and scrollTop) that lets you read or set the scroll bar | |
position of an element at the pixel level. So, if we call $('.outer').scrollLeft() and it returns | |
zero (0) we know the scroll bar is all the way to the left. | |
If the scroll bar is all the way to the right the value of .scrollLeft() will be the width of the | |
inner element minus the width of the container. We will see how this fits in next. | |
*/ | |
/* | |
If we call $('.outer').scrollLeft(($('.outer > div').width() - $)/ 2); it will set the scroll bar half | |
way. | |
Lets examine the following code: | |
*/ | |
var outer = $j('.outer'); | |
var inner = $j('.outer > div'); | |
outer.scrollLeft( (inner.width() - outer.width()) / 2) | |
/* | |
This code will set the scroll bar to the center of the inner content. | |
But lets examine why. We know the minimum value for scrollLeft is zero, and the maximum | |
is inner.width() - outer.width(). So, half way is easily half the maximum. Simple! Now, this can | |
still fail. If your inner element has padding or a margin or border then the value of .width() | |
will be incorrect. You should use .outerWidth(true), which includes the border, padding | |
and (because we passed true) the margin. | |
*/ | |
/* | |
So, how will we get it to center on an arbitrary element in the list. We use a very similar method | |
to the one above, except we also need the width of the target element. | |
First, we should setup some variables | |
*/ | |
var target = $j('li.active'); //Lets assume one element has the class active, it is the one we want to center | |
var x = outer.width(); | |
var y = target.outerWidth(true); | |
var z = target.index(); //Tells us what position this is in. Useful in calculations | |
var r = (x - y) / 2; /*Should be familiar. This is how many pixels the target needs to be to the right | |
to appear centered. From our CSS we know that x should be 300 and y 120. | |
So, r= 400-120 /2 = 140 */ | |
var s = y * z; /*z is the index of the target. That means if z=3, there are 3 other elements preceding | |
our target (the first element is index zero (0) as with most indexing). | |
y is the width of our target, which from our CSS should be 120. This calculation lets | |
us know exactly how many pixels preceded our target. 3 * 120 = 360 pixels. */ | |
var t = s - r; | |
outer.scrollLeft(Math.max(0, t)); /*Our target is now centered. */ | |
/* | |
So, why does s - r center our target? We know that: | |
s = 360 -> The total number of pixels between the target's left edge and the left edge of it's container | |
r = 140 -> The total number of pixels we need to show to the left of the target to center it. | |
That means we need to hide s - r, or 360 - 140, or 220 pixels off the screen. | |
I hope this made sense to you. It really is super simple stuff, but good to have down somewhere. | |
*/ | |
/* | |
This will of course only work if each element is the same width. If they are not the same the change is | |
very simple and is in the next file. | |
If I messed something up let me know on twitter @razialx | |
Tim Reynolds | |
*/ | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function centerItFixedWidth(target, outer){ | |
var out = $(outer); | |
var tar = $(target); | |
var x = out.width(); | |
var y = tar.outerWidth(true); | |
var z = tar.index(); | |
out.scrollLeft(Math.max(0, (y * z) - (x - y)/2)); | |
} | |
function centerItVariableWidth(target, outer){ | |
var out = $(outer); | |
var tar = $(target); | |
var x = out.width(); | |
var y = tar.outerWidth(true); | |
var z = tar.index(); | |
var q = 0; | |
var m = out.find('li'); | |
//Just need to add up the width of all the elements before our target. | |
for(var i = 0; i < z; i++){ | |
q+= $(m[i]).outerWidth(true); | |
} | |
out.scrollLeft(Math.max(0, q - (x - y)/2)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment