3

I decided to try to create a tabbed menu using just CSS and HTML. Using the :target pseudo-class to show the appropriate div, I've implemented it, only it jumps around a bit too much to be user friendly:

http://brad.sebdengroup.com/newodynsite/stockman.php#StockControl

Is there anyway I can fix this? Initially, I wanted to stay away from JavaScript, but I will happily add some if it fixes this.

Note: I know I can rebuild a new tabbed menu using jQuery/some fancy library but if possible, I'd rather fix this.

Paul Sweatte
  • 24,148
  • 7
  • 127
  • 265
Andy
  • 14,427
  • 3
  • 52
  • 76
  • Explain what you mean by "jumps around too much." Do you mean that the content area that changes expands below the page and creates a scroll bar for the window? – MetalFrog Jul 27 '12 at 18:20
  • Try clicking on each of the tabs in order, because of the length of certain sub-sections, it scrolls up and down a lot – Andy Jul 27 '12 at 18:21
  • The page jumps when a scrollbar appears on the page – kb. Jul 27 '12 at 18:23
  • It does not scroll for me at all. It expands below "the fold" but it doesn't jump around. – MetalFrog Jul 27 '12 at 18:24
  • @MetalFrog What's your screen size? Mine is 1440x900 and I can recreate the problem. – Waleed Khan Jul 27 '12 at 18:25
  • 1920x1080. It still doesn't jump when I reduce my viewport. I'm expecting it to move up and down the page sporadically, am I incorrect in what I'm looking for? – MetalFrog Jul 27 '12 at 18:27
  • click on 'Sales Order Processing' then 'Customisation' – kb. Jul 27 '12 at 18:27
  • @Sam I am working on the website at work and as such I can't attempt any fixes until monday. I will try it first thing monday morning and report back – Andy Aug 04 '12 at 10:21

8 Answers8

8

Its because your using a hash value in your anchors. These cause it to jump to a div with the id specified by the hash.

To sort this you can use jQuery to stop the jumping by using .preventDefault();

You would use this by giving every anchor that jumps a class of prevent and then using jQuery to stop the jumping. Of course, you can change this selector dependant upon your html structure.

$(".prevent").click(function(e) { //Note the e for event
  e.preventDefault();
});

Edit without jQuery

After cursing not having jQuery to work with I have attempted to put together a pure js solution. You will need to check this to make sure it works on your page.

Here is the jsfiddle example.

What I have done is found all anchors on the page and then added return false into their onclick attribute. If this was to go on your live site you will need to further select the anchors, see this example and explanation:

I have also added a class to anchors you do not want to jump. To use this you will need to add a class of "menuControl" to any anchor you want to stop jumping.

Below is my JavaScript incase the jsfiddle link is broken. Just to mention but you will need to control the navigation of these tabs using JavaScript now, as using return false will stop the navigation.

var anchors = document.getElementsByTagName("a");

for(var i = 0; i < anchors.length; i++) {
    if ( anchors[i].className == "menuControl" ) {
        anchors[i].setAttribute("onclick", "return false");
    }
} ​
Undefined
  • 11,234
  • 5
  • 37
  • 62
  • No, it's because the divs have varying heights. As you can tell, it's not following the browser's default behavior by jumping to the top. It tries bring the window to the top of the div, but the window does not have sufficient height. – Nick Beranek Jul 27 '12 at 18:33
  • So by preventing default it would stop the jumping, the op didn't ask how to scroll to the top of the page. – Undefined Jul 27 '12 at 18:34
  • 1
    @Sam is correct, it's because the browser is scrolling "down" to the div with that ID. `e.preventDefault()` (and maybe a `return false`) will prevent the jumping – Dan F Jul 28 '12 at 04:41
  • I've never used jquery before, I included the .js file, added this code like you said but nothings happening, is there something I missed? – Andy Jul 31 '12 at 08:35
  • Are you sure you have included jquery on the page? Make sure you are loading jQuery above your custom code. If you could post your html on pastebin i could help further. – Undefined Jul 31 '12 at 08:37
  • @Sam by preventing the default behaviour you are completely stopping the menu from working. You will have to add javascript to show / hide the content as well. – My Head Hurts Aug 04 '12 at 11:31
  • @MyHeadHurts Good point, i'll see if i can setup some js for the OP that can do this – Undefined Aug 04 '12 at 17:29
2

You can use window.scrollTo(0, 0); after every click to scroll back to the top of the document, it will most likely happen too fast for any user to notice.

Docs

For the horizontal jump, you can use overflow-y: scroll on your body so that the scrollbar is always on the page, even if there is not enough content to cause scrolling.

jbabey
  • 45,965
  • 12
  • 71
  • 94
2

You could set the min height of the page to the height it needs to be for the div to move to the top with css.

body { min-height: 1000px; } 

Replace 1000px with however many px you need.

That would prevent all jumping beyond the initial click that makes the browser view target the div.

It would be like clicking Sales Order Processing and then clicking Works Order Processing as it is now. If you don't want all the extra white space on page load you can have the height set only when the tabs are clicked.

Smith
  • 70
  • 1
  • 8
1

I would use jQuery to make it scroll smoothly. There is a good demo here.

dezman
  • 18,087
  • 10
  • 53
  • 91
1
$(window).scroll(function () { 
       var newTop = $(window).scrollTop();
       if (newTop <= 130){
            newTop = 130;
       }
       $("#idofElementToScroll").stop()
       .animate({'top': newTop}, "slow");
});

This is a function that I wrote and implemented in the private section on my personal site.

What is happening here is you are declaring where you currently are on the screen and then as you scroll down the element that you are scrolling smoothly scrolls with you.

I know that you were asking for moving the anchors, but you can adapt this function to that purpose very easily.

Please note that the '130' is referring to the minimum distance that I wanted the moving element to be from the top of the window.

Good Luck!

Zachary Kniebel
  • 4,686
  • 3
  • 29
  • 53
  • @user1538100: a co-worker of mine posted this solution to your question a while back in another stack overflow post http://stackoverflow.com/questions/1890995/jquery-scroll-to-bottom-of-page-iframe/1891142#1891142 – Zachary Kniebel Jul 28 '12 at 19:01
1

You've got a problem, because your container heights are so different.

I suggest you wrap all of your content containers in a style-less div. Then loop through all the containers. Compute the maximum height of the containers. Then give all the wrapping divs this maximum height.

yunzen
  • 32,854
  • 11
  • 73
  • 106
0

Use the sibling selector with the target pseudo-class to avoid this issue, following the example of Stu Nicholls, but beware of the Webkit bug:

<!doctype html>
<html lang="en">
<head>
    <title>CSS Target Navigation</title>
    <style type="text/css">
/* ================================================================ 
This copyright notice must be untouched at all times.

The original version of this stylesheet and the associated (x)html
is available at http://www.cssplay.co.uk/menus/cssplay-page-menu.html
Copyright (c) Stu Nicholls. All rights reserved.
This stylesheet and the associated (x)html may be modified in any 
way to fit your requirements.
=================================================================== */

#cssplayPages {width:690px; height:400px; position:relative; margin:20px auto;}
#cssplayPages #navigate {padding:0; margin:35px 0 0 0; list-style:none; width:160px; text-align:right; float:left;}
#cssplayPages #navigate li {float:left; width:160px; margin:0 0 5px 0;}
#cssplayPages #navigate li a {display:block; width:140px; padding:0 10px; background:#ddd; font:bold 13px/35px arial, sans-serif; text-decoration:none; color:#000; border-radius:5px;
-moz-transition: 0.5s;
-ms-transition: 0.5s;
-o-transition: 0.5s;
-webkit-transition: 0.5s;
transition: 0.5s;
}
#cssplayPages #navigate li a:hover {background:#6cf;}

#cssplayPages #navigate.john a {background:#6cf;}

.targets {display:none;}
#cssplayPages div {position:absolute; width:0; left:190px; top:0; opacity:0; height:0px; overflow:hidden;
-moz-transition: 1.5s;
-ms-transition: 1.5s;
-o-transition: 1.5s;
-webkit-transition: 1.5s;
transition: 1.5s;
}
#cssplayPages div.constable {height:400px; width:500px; opacity:1;}

#cssplayPages div img {float:left; padding:0 10px 10px 0;}
#cssplayPages div h2 {padding:0 0 10px 0; margin:0; font: 24px/24px arial, sans-serif;}
#cssplayPages div p {padding:0 0 10px 0; margin:0; font: 13px/18px arial, sans-serif; text-align:justify;}


#constable:target ~ #navigate .john a {background:#6cf;}
#constable:target ~ .constable {height:400px; width:500px; opacity:1;}

#monet:target ~ #navigate .claude a {background:#6cf;}
#monet:target ~ #navigate .john a {background:#ddd;}
#monet:target ~ #navigate .john a:hover {background:#6cf;}
#monet:target ~ .constable {height:0; width:0; opacity:0;}
#monet:target ~ .monet {height:400px; width:500px; opacity:1;}

#vangogh:target ~ #navigate .vincent a {background:#6cf;}
#vangogh:target ~ #navigate .john a {background:#ddd;}
#vangogh:target ~ #navigate .john a:hover {background:#6cf;}
#vangogh:target ~ .constable {height:0; width:0; opacity:0;}
#vangogh:target ~ .vangogh {height:400px; width:500px; opacity:1;}

#chagall:target ~ #navigate .marc a {background:#6cf;}
#chagall:target ~ #navigate .john a {background:#ddd;}
#chagall:target ~ #navigate .john a:hover {background:#6cf;}
#chagall:target ~ .constable {height:0; width:0; opacity:0;}
#chagall:target ~ .chagall {height:400px; width:500px; opacity:1;}

#picasso:target ~ #navigate .pablo a {background:#6cf;}
#picasso:target ~ #navigate .john a {background:#ddd;}
#picasso:target ~ #navigate .john a:hover {background:#6cf;}
#picasso:target ~ .constable {height:0; width:0; opacity:0;}
#picasso:target ~ .picasso {height:400px; width:500px; opacity:1;}
</style>

</head>
<body>
    <div id="cssplayPages">
    <b class="targets" id="constable"></b>
    <b class="targets" id="monet"></b>
    <b class="targets" id="vangogh"></b>
    <b class="targets" id="chagall"></b>
    <b class="targets" id="picasso"></b>
    <ul id="navigate">
        <li class="john"><a href="#constable" onClick="history.go(1)">John Constable &#9755;</a></li>
        <li class="claude"><a href="#monet" onClick="history.go(1)">Claude Monet &#9755;</a></li>
        <li class="vincent"><a href="#vangogh" onClick="history.go(1)">Vincent Van Gogh &#9755;</a></li>
        <li class="marc"><a href="#chagall" onClick="history.go(1)">Marc Chagall &#9755;</a></li>
        <li class="pablo"><a href="#picasso" onClick="history.go(1)">Pablo Picasso &#9755;</a></li>
    </ul>
    <div class="constable">
        <h2>John Constable</h2>
        <img src="painters/constable2.jpg" alt="The Hay Wain" title="The Hay Wain" />
        <p>Although he showed an early talent for art and began painting his native Suffolk scenery before he left school, his great originality matured slowly.</p>
        <p>He committed himself to a career as an artist only in 1799, when he joined the Royal Academy Schools and it was not until 1829 that he was grudgingly made a full Academician, elected by a majority of only one vote.</p>
        <p>In 1816 he became financially secure on the death of his father and married Maria Bicknell after a seven-year courtship and in the fact of strong opposition from her family. During the 1820s he began to win recognition: The Hay Wain (National Gallery, London, 1821) won a gold medal at the Paris Salon of 1824 and Constable was admired by <a href="http://www.ibiblio.org/wm/paint/auth/delacroix/">Delacroix</a> and Bonington among others.</p>
        <p>His wife died in 1828, however, and the remaining years of his life were clouded by despondency.</p>
        <p>This text is an excerpt from <a href="http://www.ibiblio.org/wm/paint/auth/constable/">The&nbsp;WebMuseum,&nbsp;Paris</a></p>
    </div>
    <div class="monet">
        <h2>Claude Monet</h2>
        <img src="painters/monet2.jpg" alt="Women in the Garden" title="Women in the Garden" />
        <p>His youth was spent in Le Havre, where he first excelled as a caricaturist but was then converted to landscape painting by his early mentor <a href="http://www.ibiblio.org/wm/paint/auth/boudin/">Boudin</a>, from whom he derived his firm predilection for painting out of doors.</p>
        <p>In 1859 he studied in Paris at the Atelier Suisse and formed a friendship with <a href="http://www.ibiblio.org/wm/paint/auth/pissarro/">Pissarro</a>. After two years' military service in Algiers, he returned to Le Havre and met <a href="http://www.ibiblio.org/wm/paint/auth/jongkind/">Jongkind</a>, to whom he said he owed `the definitive education of my eye'.</p>
        <p>He then, in 1862, entered the studio of Gleyre in Paris and there met Renoir, Sisley, and Bazille, with whom he was to form the nucleus of the Impressionist group.</p> 
        <p>Monet's devotion to painting out of doors is illustrated by the famous story concerning one of his most ambitious early works, Women in the Garden (Mus&#233;e d'Orsay, Paris; 1866-67). The picture is about 2.5 meters high and to enable him to paint all of it outside he had a trench dug in the garden so that the canvas could be raised or lowered by pulleys to the height he required.</p>
        <p>This text is an excerpt from <a href="http://www.ibiblio.org/wm/paint/auth/monet/">The&nbsp;WebMuseum,&nbsp;Paris</a></p>
    </div>
    <div class="vangogh">
        <h2>Vincent Van Gogh</h2>
        <img src="painters/vincent2.jpg" alt="The Starry Night" title="The Starry Night" />
        <p>Gogh, Vincent (Willem) van (b. March 30, 1853, Zundert, Neth.--d. July 29, 1890, Auvers-sur-Oise, near Paris), generally considered the greatest Dutch painter and draughtsman after <a href="http://www.ibiblio.org/wm/paint/auth/rembrandt/">Rembrandt</a>.</p>
        <p>With <a href="http://www.ibiblio.org/wm/paint/auth/cezanne/">C&#233;zanne</a> and <a href="http://www.ibiblio.org/wm/paint/auth/gauguin/">Gauguin</a> the greatest of Post-Impressionist artists. He powerfully influenced the current of <a href="http://www.ibiblio.org/wm/paint/glo/expressionism/">Expressionism</a> in modern art. His work, all of it produced during a period of only 10 years, hauntingly conveys through its striking colour, coarse brushwork, and contoured forms the anguish of a mental illness that eventually resulted in suicide. Among his masterpieces are numerous self-portraits and the well-known <a href="http://www.ibiblio.org/wm/paint/auth/gogh/starry-night/">The&nbsp;Starry&nbsp;Night</a> (1889).</p> 
        <p>This text is an excerpt from <a href="http://www.ibiblio.org/wm/paint/auth/gogh/">The&nbsp;WebMuseum,&nbsp;Paris</a></p>
    </div>
    <div class="chagall">
        <h2>Marc Chagall</h2>
        <img src="painters/chagall2.jpg" alt="Adam and Eve" title="Adam and Eve" />
        <p>Russian-born French painter. Born to a humble Jewish family in the ghetto of a large town in White Russia, Chagall passed a childhood steeped in Hasidic culture.</p>
        <p>Very early in life he was encouraged by his mother to follow his vocation and she managed to get him into a St Petersburg art school. Returning to Vitebsk, he became engaged to Bella Rosenfeld (whom he married twelve years later), then, in 1910, set off for Paris, 'the Mecca of art'.</p>
        <p>He was a tenant at La Ruche, where he had Modigliani and Soutine for neighbours. His Slav Expressionism was tinged with the influence of <a href="http://www.artchive.com/artchive/D/daumier.html">Daumier</a>, Jean-Fran&#231;ois Millet, the Nabis and the Fauves.</p>
        <p>He was also influenced by <a href="http://www.artchive.com/artchive/cubism.html">Cubism</a>. Essentially a colourist, Chagall was interested in the Simultaneist vision of Robert Delaunay and the Luminists of the Section d'Or.</p>
    </div>
    <div class="picasso">
        <h2>Pablo Picasso</h2>
        <img src="painters/picasso2.jpg" alt="Girtl in front of mirror" title="Girtl in front of mirror" />
        <p>Pablo Picasso, born in Spain, was a child prodigy who was recognized as such by his art-teacher father, who ably led him along.</p>
        <p>The small Museo de Picasso in Barcelona is devoted primarily to his <a href="http://www.artchive.com/artchive/P/picasso_early.html">early works</a>, which include strikingly realistic renderings of casts of ancient sculpture.</p>
        <p>He was a rebel from the start and, as a teenager, began to frequent the Barcelona cafes where intellectuals gathered.</p>
        <p>He soon went to Paris, the capital of art, and soaked up the works of Manet, Gustave Courbet, and <a href="http://www.artchive.com/artchive/T/toulouse-lautrec.html">Toulouse-Lautrec</a>, whose sketchy style impressed him greatly. Then it was back to Spain, a return to France, and again back to Spain - all in the years 1899 to 1904.</p>
    </div>
</div>

            <p class="info">copyright &copy; stu nicholls - CSS play</p>

        </div> <!-- end info -->

</body>
</html>
Paul Sweatte
  • 24,148
  • 7
  • 127
  • 265
0

Here is another suggestion:

<style>
    nav ~ div {
        display: none;
    }

    .tab {
        position:fixed;
        top:0;
    }

    :target:not([id="box1"]) ~ .box1 {
        display: none;
    }

    #box1:target ~ nav .box1,
    #box2:target ~ nav .box2,
    #box3:target ~ nav .box3 {
        color:red;
    }

    #box1:target ~ div.box1,
    #box2:target ~ div.box2,
    #box3:target ~ div.box3 {
        display:block;
    }
</style>

<section id="content">
    <div id="box1" class="tab"></div>
    <div id="box2" class="tab"></div>
    <div id="box3" class="tab"></div>
    <nav>
         <a href="#box1" class="box1">box1</a>
         <a href="#box2" class="box2">box2</a>
         <a href="#box2" class="box3">box3</a>
    </nav>
    <div class="box1">
         blah
    </div>
    <div class="box2">
         blah
    </div>
    <div class="box3">
         blah
    </div>
</section>

That should do the trick as the anchors are fixed. It could jump once but then it won't anymore.