Horizontal Scrolling - Centering a DIV from #ID?

This is rattling my brain.

I have a horizontal scrolling website where there are several divs layed out horizontally across the page. The problem is when I click a link #id to scroll to each div they will appear on the left of the screen.

Is there anyway to get each div despite it’s width, to get centered dead in the middle of the screen when a #id link is clicked?

I think there are some ways to do that, but that would involve extra code and would not be thoroughly tested.

If a solution is practical also depends on the structure of your site,

I would think that for an automatic (fluid) solution that a javascript solution would be needed to scroll the selected element to the middle of the screen as the fragment identifier doesn’t scroll the element to the far left at all times. It depends on the length of the element and whether it is already visible or not. You can’t assume that the scrolled element will appear at the left so it would be difficult to consistently offset it with css alone.

If you have control of the number of items beforehand and you don’t mind them being 100% apart then you could do this in CSS.

e.g.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style>
*{margin:0;padding:0}
.test {
    float:left;
    width:1000%;/* i.e. ten elements of 100% width */
    padding:250px 0 0;
}
.test div {
    float:left;
    width:10%;/* make each element as wide as the viewport*/
    height:200px;
    margin:10px 0;
    position:relative;
}
.test div div{
    background:yellow;
    margin:auto;/* center nested element in 100% width*/
    float:none;
}
.test #a div{width:500px}
.test #b div{width:200px}
.test #c div{width:700px}
.test #d div{width:100px}
.test #e div{width:800px}
.test #f div{width:300px}
.test #g div{width:200px}
.test #h div{width:100px}
.test #i div{width:250px}
.test #j div{width:450px}

ul{position:fixed;left:100px;top:20px;}

</style>
</head>
<body>
<ul>
    <li><a href="#a">Go to box 1</a></li>
    <li><a href="#b">Go to box 2</a></li>
    <li><a href="#c">Go to box 3</a></li>
    <li><a href="#d">Go to box 4</a></li>
    <li><a href="#e">Go to box 5</a></li>
    <li><a href="#f">Go to box 6</a></li>
    <li><a href="#g">Go to box 7</a></li>
    <li><a href="#h">Go to box 8</a></li>
    <li><a href="#i">Go to box 9</a></li>
    <li><a href="#j">Go to box 10</a></li>
</ul>
<div class="test">
    <div id="a"><div>test 1</div></div>
    <div id="b"><div>test 2</div></div>
    <div id="c"><div >test 3</div></div>
    <div id="d"><div>test 4</div></div>
    <div id="e"><div >test 5</div></div>
    <div id="f"><div>test 6</div></div>
    <div id="g"><div>test 7</div></div>
    <div id="h"><div >test 8</div></div>
    <div id="i"><div>test 9</div></div>
    <div id="j"><div>test 10</div></div>
</div>
</body>
</html>


(The fixed nav won’t work in IE6)

Actually Paul, you are slightly incorrect about the need for JavaScript, if you remember my new look website whilst it isn’t currently perfect (admittedly) what it does achieve through the horizontal scroller is a group of panels which each span 100% of the pages width (ensuring there are no visible overlaps occurring) and the panel for each is carefully balanced in the center of the screen (as required), this is why I went with my own interpretation of the horizontal scrolling technique (to ensure such a balance occured). However as this requires percentage measurements it also means that a fixed percentage width must be given which accounts for the contents at 100% the available dimensions width (took me a while to calculate it right!). Might be helpful for the OP to check out my new design for themselves to see how I generally went about it. In it’s simplest terms mine was 6 panels (600% wide container with each item at 16.66% wide to account for the 100% of each balanced to the center using margin: 0 auto. This means no matter how much screen space is available it’ll scale to meet the page widths. I also apply the ID’s to the panel with 16.66% (or whatever) as this means the page will force the ID to scroll to the section which spans the page (ensuring the center aligned element is central).

The calculation I used was… wrapper = num(00) | panel = 100/N

This means the wrappers width must be equal to the number of panels with two 0’s after it (so 10 panels would be 1000% or 6 panels = 6000% width to the wrapper) and the panels themselves would be 50 divided by the number of panels multiplied by two (so 100 / 6 = 16.66%), a bit complicated I know but it works perfectly for me in calculating the widths required for containers and each panel. And now you see while less agile than the example you pointed me too, there was a reason why I used my weird method (I couldn’t find another example of it in the wild so built it up from scratch and it works in every browser - including IE6), I’ve no issues if anyone want’s to replicate the effect using percentage widths to force a central flowing horizontal scaling design, so feel free to experiment… I’m working on cleaning it up… but essentially the key is in the 600% wide container, 16.66% wide panels (to scale 100% of the pages width) and the contents being aligned within the space! :slight_smile:

I would agree with using Javascript, unless you don’t care about your in-page links when the page isn’t horizontal (such as when someone gets the page without CSS). One thing I found that seemed to work cross-browser was to simply put the “next link” one link too far. That way, the actual link destination ended up on the right side of the screen and the part you actually wanted to see was simply ON the screen.

But the drawback is, your links make absolutely no sense in a non-visual context or if the page ever goes to non-horizontal. My own horizontal site considered this (as almost all browsers moved the destination to the exact right side/edge of the screen), but didn’t do it for the reasons above (it needed to make sense without horizontalness). Also, the page, unlike Alex’s, does not have a set width. Some pages may be added to until they scroll to the browser’s limit (Opera has a limit, so I assume possibly all browsers ultimately have a width limit) while other pages were barely wider than a screen.

Stomme, there is a reason why I set explicit width’s, it was to ensure that each panel would span the full 100% the page had to offer. An example would be say you had 4 sections you wished to have span 100% of the page width… the way to achieve this would be to have a 400% wide container with it’s contents spanning 25%, that 25% of 400% = 100% therefore it’s guaranteed to ONLY use the amount of space available to it in percentages, the only issue with this implementation is Opera has a quirk with issuing width’s in percentages beyond the default (I got around this by declaring min-width along with the 16.66% in my design which fixes the glitch nicely). My point is if each “panel” spans exactly 100% of the available space (and the rest is in overflow stacked using floats), the contents of that panel can be centrally aligned using margin auto (with the anchor fragment linked to the 100% wide component) and it guarantees a central loading section in every browser. :slight_smile:

PS: As it’s relevant to the discussion my URL is http://www.hitechy.com/ (I am in the process of making it more agile but the thing works perfectly in IE6+, FF, O, S, C). The JavaScript patch in the source code is to deal with something entirely different (I’m attempting pure CSS lightboxes - except for IE which doesn’t like CSS3) :wink:

That could work for 100% wide pages in the first place. A brochure site would be best suited to something like that, because a brochure has a fixed amount of information. Or, you’d need to set a different width for each page on the site. That was something I’d rather not do.

Actually, even though it’s not visible within the design if the information did overflow the space assigned to it, vertical scrollbars are introduced to allow the information to expand within the fixed region cleanly without impacting the design, it’s like having iframes within the page except it’s much more accessible and semantic :slight_smile:

Did you read my post Alex :slight_smile:

Look at the demo I posted and then re-read what I said :slight_smile:

This seems to be exactly what you are suggesting.

Sorry I misread your post Paul. That’s exactly what I was hinting at, though if an automatic layout is what they wanted it might be possible either using min/max-width or using a large width and some clever uses of overflow. Perhaps I’ll have a play around with it some-when to try and see if it’s possible to accomplish without resorting to using JavaScript. I actually reported a bug to Opera not long ago in how it calculates percentages as a result of achieving this scrolling effect. :slight_smile:

lol - No problems :slight_smile:

Yes that’s a long standing opera bug and opera has never played ball with fractions of percentages. I mentioned it in this demo about 5 years ago and it still isn’t fixed n opera10.

Well I’ve submitted an official bug report to them over the quirk Paul (with the exact situation I have been getting with strange percentage and margin issues) and when I get time I’m going to submit the issue myself into the CSS 2.1 testing suite (James Hopkins has been kindly pointing me in the direction for getting these annoying quirks recognised), Opera tend to take notice of the working groups so perhaps getting it submitted will push it forward :slight_smile:

Nice method Paul. Will that work if the DIV’s are positioned absolute?

Interesting problem. Here’s a proof of concept; works in Firefox and Google Chrome. Opera fails oddly. I need to look at it more closely. Not tested in IE. For some reason cross porting is too much for MSFT to handle. :smiley:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
      xml:lang="en-US"
      lang="en-US">
<head>
  <meta http-equiv="Content-Type"
        content="text/html; charset=utf-8" />

  <title>Horizontal scrolling by panels</title>
  <style type="text/css">
/*<![CDATA[*/
  body, html {
    padding: 0;
    margin: 0;
    }

  body.hscrolling {
    white-space: nowrap;
    }

  /* Images are made block and centered as an example for galleries */
  img {
    display:  block;
    margin: 0 auto;
    }

  .panel {
    display: inline-block;
    vertical-align: top;
    white-space: normal;
    width: 100%;
    }

* html .panel {
    display: inline;
    }

  .panel>div {
    border: 1px dotted gray;
    display: table;
    margin: 1.25em auto 0;
    }

  .panel>div p {
    padding: 0 1.25em;
    }

  p.link {
    text-align: right;
    }

  p.link a[rel="prev"] {
    float: left;
    }

  /*]]>*/
  </style>
</head>

<body class="hscrolling">
  <div class="panel"
       id="p1">

    <div>
      <p>Specimen content; a short paragraph.</p>

      <p class="link"><a href=""
         rel="prev"></a><a href="#p2"
         rel="next">Next</a></p>
    </div>
  </div>

  <div class="panel"
       id="p2">
    <div>

      <p>Longer, multiple paragraphs.</p>

      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean risus
      sem, tristique eget malesuada nec, imperdiet vel odio. Quisque cursus
      consequat nisl non ultricies. Phasellus id enim quis massa porttitor
      sodales vel sit amet augue. Integer vitae felis commodo quam aliquam
      consectetur. Vestibulum non tempor nibh. Ut ligula lorem, ultricies non
      venenatis a, egestas vel purus. Nullam vulputate elit ut tortor lacinia
      tristique? Suspendisse nibh nisl; ornare at dignissim ac; hendrerit nec
      dolor. Praesent eget nisl nec lectus bibendum sodales et eget purus.
      Phasellus pulvinar, lorem id consequat iaculis, quam ipsum blandit lacus,
      ac laoreet nisl diam nec odio. Class aptent taciti sociosqu ad litora
      torquent per conubia nostra, per inceptos himenaeos. Aliquam a dolor
      nulla. Proin suscipit, arcu varius pellentesque tincidunt; magna leo
      rutrum lorem, sed pellentesque lorem enim eget sem? Nunc commodo tempus
      turpis eu interdum. Cras tempus, orci id laoreet consectetur, ipsum mi
      sagittis lectus, ac elementum nulla nisi ac felis. Praesent luctus ligula
      at velit sollicitudin ornare. Nulla id libero neque, sed ultricies
      est.</p>

      <p class="link"><a href="#p1"
         rel="prev">Prev</a><a href="#p3"
         rel="next">Next</a></p>
    </div>
  </div>

  <div class="panel"
       id="p3">
    <div>
      <img src="smoothing-plane.png"
           alt="Drawing of a smoothing plane" />

      <p class="link"><a href="#p2"
         rel="prev">Prev</a><a href=""
         rel="next"></a></p>
    </div>
  </div>
</body>
</html>

cheers,

gary

When I posted I was thinking of solutions for any widths and different content in those centred divs. Here is one cross-browser solution for varying content and panel sizes. I did chose a hidden vertical scroll instead of the usual horizontal scrollbar thinking the purpose of the concept is the instant panel swapping, not the actual scrolling which I think can only be annoying. A vertical stacking does also keep panel position if the user resizes viewport width. (A height change after a panel switch would need to reposition current panel.)

The css works with any number of panels and it is easy to add a fixed head and footer to the page that is also working in IE6 and still replacing any standard scrollbars without overlap (the system settings can differ).

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head><meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<title>Instant Panel Swapping</title>
<meta name="generator" content="PSPad editor, www.pspad.com">
<style type="text/css">
html,
body {
	margin: 0;
	padding: 0;
	width: 100%;
	height: 100%;
	overflow: hidden;
}
.panel {
	width: 100%;
	height: 100%;
	overflow: auto;
	overflow-y: scroll;
}
.panel div {
	margin: auto; 
	padding: 10px ;
	background: pink;
}
/* demo settings */
#panel1 div{width:50%}
#panel2 div{width:50%}
#panel3 div{width:30em}
#panel4 div{width:90em}
</style>
</head><body>

<div id="panel1" class="panel">
	<div>
		<p><a href="#panel3">Change to 30em container width</a></p>
		<p><a href="#panel2">Try more content at 50% width</a></p>
		<p>Lorem ipsum dolor sit amet consectetuer et congue ridiculus dui Sed. Enim sed Cras Lorem vitae.</p>
		<p>In leo neque et et nulla interdum accumsan congue sodales pede. Elit.</p>
		<p>Curabitur ipsum penatibus volutpat pellentesque sit nunc id diam eget nec. Augue semper congue amet.</p>
	</div>
</div>

<div id="panel2" class="panel">
	<div>
		<p><a href="#panel3">Change to 30em container width</a></p>
		<p><a href="#panel1">Try less content at 50% width</a></p>
		<p>Lorem ipsum dolor sit amet consectetuer et congue ridiculus dui Sed. Enim sed Cras Lorem vitae.</p>
		<p>In leo neque et et nulla interdum accumsan congue sodales pede. Elit.</p>
		<p>Curabitur ipsum penatibus volutpat pellentesque sit nunc id diam eget nec. Augue semper congue amet.</p>
		<p>Platea vitae habitasse Proin pulvinar quam Pellentesque vitae urna lacinia congue. At interdum consequat nulla nunc Mauris et nulla laoreet. Senectus netus nec consequat. Leo enim wisi commodo metus mi wisi eget a nisl Praesent. Accumsan Integer Vestibulum tincidunt pede Sed lorem Nulla hendrerit. Aliquam faucibus et interdum nibh eget. Nec leo Phasellus eget ut quis.</p>
		<p>Velit a ut Aenean et pellentesque condimentum eros orci lacus Phasellus. Aenean ipsum facilisis cursus netus Pellentesque nibh semper consequat neque neque. Nibh dis eget Ut libero vitae et arcu lorem id nonummy. Fringilla leo vitae dapibus vel Suspendisse Ut nascetur mattis risus Nunc. Elit volutpat ut. Hac vitae eu tortor Nullam ac.</p>
		<p>Lorem ipsum dolor sit amet consectetuer purus montes quis Sed fringilla. Metus nonummy condimentum non id massa ornare Sed laoreet eget sed. Libero nibh accumsan mi pellentesque sem. Malesuada cursus venenatis Maecenas tortor pretium sapien turpis id tincidunt ut. Sem euismod convallis commodo suscipit pede ligula Aenean massa Nam non. Proin tellus venenatis.</p>
		<p>Porttitor Suspendisse a egestas lacinia ac turpis vitae massa pede metus. Mollis Curabitur hendrerit tempus eget elit nisl mattis Nunc neque nulla. Id est et. Tincidunt justo ac morbi lacinia tortor adipiscing nisl metus tristique sagittis. Adipiscing nibh tempus Vestibulum ullamcorper semper lorem Quisque Nulla rutrum amet. Eget nascetur convallis Aenean.</p>
		<p>Est ac platea et fermentum mauris at nec Praesent dolor tincidunt. Semper tellus tortor interdum in et eget urna sit semper Lorem. Id consequat et est. Egestas egestas sagittis tempus Quisque mi Aliquam semper sed nec mauris. Lorem congue ligula tincidunt nonummy elit et justo Pellentesque et tellus. Ac Pellentesque nulla vel senectus tempor elit.</p>
		<p>Nibh dis eget Ut libero vitae et arcu lorem id nonummy. Fringilla leo vitae dapibus vel Suspendisse Ut nascetur mattis risus Nunc. Elit volutpat ut. Nisl id Curabitur hendrerit scelerisque nibh tellus platea est felis platea. Dictum dictumst condimentum dolor lacus hac quis Proin elit malesuada eu. Id vitae cursus.</p>
	</div>
</div>

<div id="panel3" class="panel">
	<div>
		<p><a href="#panel4">Try 90em container width</a></p>
		<p><a href="#panel1">Change amount of content</a></p>
		<p>Platea vitae habitasse Proin pulvinar quam Pellentesque vitae urna lacinia congue. At interdum consequat nulla nunc. Senectus netus nec consequat. Leo Mauris et nulla laoreet enim wisi commodo metus mi. Accumsan wisi eget a nisl Praesent Integer Vestibulum tincidunt pede Sed lorem Nulla hendrerit. Aliquam faucibus et interdum nibh eget. Nec leo Phasellus eget ut quis.</p>
	</div>
</div>

<div id="panel4" class="panel">
	<div>
		<p><a href="#panel3">Try 30em container width</a></p>
		<p><a href="#panel1">Change  amount of content</a></p>
		<p>Platea vitae habitasse Proin pulvinar quam Pellentesque vitae urna lacinia congue. At interdum consequat nulla nunc. Senectus netus nec consequat. Leo Mauris et nulla laoreet enim wisi commodo metus mi. Accumsan wisi eget a nisl Praesent Integer Vestibulum tincidunt pede Sed lorem Nulla hendrerit. Aliquam faucibus et interdum nibh eget. Nec leo Phasellus eget ut quis.</p>
	</div>
</div>

</body></html>

zompus, You don’t need AP to centre the divs. :slight_smile:

But if you need AP anything in the panels, just remember to give relative position to the panel div-containers, and for IE also to the panel-divs and the body to handle the positioned children.

I’ve used AP to not center the divs but position them.

I figure I best just show the page to avoid confusion on what I’m trying to achieve.

Ignore the sloppy code, poorly optimised images, bad load times etc. I’ll work on these once i’ve got it all working.

I’m thinking javascript is probably the way to go or add a % padding to each div get it some distance away from the edges.

Interesting Demos Gary and Erik (I could have used this in a quiz :)).

Erik your demo reminds me of a previous quiz where we did a hide and show with dropdowns but without js. :slight_smile:

Zompus you already seem to be using jquery to scroll the elements so your best option would be to adjust the js to suit. I believe the scrollTo function has some built in centering parameters but you would need to research that in the js forum.

Okay, cheers Paul. (:

First option was to do it with CSS but I see it’s pretty futile now.

[QUOTE=zompus;]…
I’m thinking javascript is probably the way to go or add a % padding to each div get it some distance away from the edges.[/QUOTE]
It is your choice, but I think Paul gave a good start for another solution. :slight_smile:

Anyway, I wouldn’t let a the users ability to surf the site depend on site external javascript. The only content reachable from the intro panel would be the default link targets. I suggest adding creative link options for non javascript surfers. I for one, rarely (ever) turn javascript on to view a site. To tease you I’ll cite your About panel: “Design in the absence of content is not design,”. (Sorry, couldn’t resist :smiley: )

Said that, I find your page is well suited to adapt solutions from this thread. In them also your two fixed nav-links can be made fixed in IE6 too. If you had given the link first, I think you would already have been given precise suggestions how to make it all work. :wink:

Edit) I forgot hitting the post button two hours ago. Still relevant though. :slight_smile:

It did pop up in my mind, but as posting went on I let it be. I felt a quiz solution then would need a real challenge, like adding to the horizontal centre a vertical centre mechanism not hiding extended content.

And yes, I’ve made some testing on that technique. :slight_smile:

Glad to hear. Why is it now futile do you think?