5

I have my markup as follows:

<li><a href="#sheds_housing">Sheds &amp; Housing</a></li>
<div id="sheds_housing">
    <h1>sheds &amp; housing</h1>
    <img src="images/cattle/sheds_housing.png" width="150" height="150" alt="Sheds & Housing"
        title="Sheds & Housing" />
    <p>Text here</p>
</div>

to create a link to a section of the page so that when users clicks the anchor, it takes him to that section.

Is there anyway I can make sure that when a user does so, the content always shows at the top without any extra content that maybe present in the normal flow of the document above the linked div.

Can it be done with CSS alone or do I have to use JS/jQuery for this, and if yes what code?

EDIT

I was not clear before; See this Fiddle. If you click the first two links, you will be taken to the respective sections and the content will appear at the top of the window but if you click the last link, you will be taken to the respective section but the content will not appear at the top of the window and the content that sits above the respective sections is present.

Ilan Biala
  • 3,319
  • 5
  • 36
  • 45
Jawad
  • 8,352
  • 10
  • 40
  • 45
  • It all depends on the height of the content and I seek a solution where the height does not matter. If height is long enough, it will work but not vice versa. – Jawad Sep 02 '12 at 17:42
  • someone, somewhere must know how to do this. – Jawad Sep 02 '12 at 18:09
  • I really for the life of me can't get the downvotes. – Jawad Sep 02 '12 at 18:34
  • I've changed my answer to show how to implement the CSS class. (JSFiddle) – Nate-Wilkins Sep 02 '12 at 20:15
  • @Nate: Don't see any updated Fiddle! – Jawad Sep 03 '12 at 07:49
  • Hehe… Here's a weird effect found in my attempt at an answer :-p http://jsfiddle.net/dKfVL/1/ Putting a wrapper around the `#content`, then making the wrapper `overflow: hidden;` and adding `padding-bottom: 3000em; margin-bottom: -3000em;` to the content makes things interesting in Webkit. It scrolls the content to the linked `DIV`, but hides everything else with no way to get it back :-p Different browsers probably exhibit different behaviors I'd imagine… – thirdender Sep 04 '12 at 21:49
  • @thirdender: LOL I wonder why would that happen. – Jawad Sep 05 '12 at 08:30
  • @thirdender Is it a strange use of One True Layout technique? Nice one (that works on Firefox too)! :) I just stumbled upon it in a recent answer to a different question: http://stackoverflow.com/a/12322364/137626 IMHO you should post it as an answer, seems like the best one if it works in different versions of IE. – FelipeAls Sep 07 '12 at 21:34
  • @thirdender It works in IE8 and Safari 4, fails in IE6 and IE7. It'll scroll in Opera but the One True Layout technique itself has a problem with this browser (in JSFiddle demos at least). It will leave a huge white gap in Opera 11 and not so huge in 12.x. All in all good enough. – FelipeAls Sep 07 '12 at 21:43
  • @FelipeAls, eh, I felt like not being able to got back to the contents easily made unusable… and I couldn't think of a way to fix that… – thirdender Sep 08 '12 at 16:04
  • `#content div:last-child { position: absolute; height: 100% !important; background-color:blue; }` – ChristopheCVB Sep 11 '12 at 15:18
  • got an answer for you :) – RASG Sep 11 '12 at 17:34

12 Answers12

4

Add the id "last_anchor" to the last link in your list and this will achieve it with jquery. How and if you decide to change the margin of the body back is up to you...

$(document).ready(function(){
  $("#last_anchor").click(function(){
    var content_id = $(this).attr("href");
    var win_height = $(window).height();
    var content_height = $(content_id).height();
    var target_margin = win_height - content_height;
    $("body").css("margin-bottom", target_margin)
  });
});​
Matthew
  • 146
  • 2
2

the content always shows at the top without any extra content that maybe present in the normal flow of the document above the linked div.

Assuming this means that you want to hide all the sections on the page and just show the section corresponding to the link clicked, what you are looking for is referred to as Accordian, you can find a sample one here.

Vikdor
  • 23,934
  • 10
  • 61
  • 84
2

The problem is (if I understand correctly!) you are hitting the end of the page. If you extend the margin on the last element or add some content the header will show on top (if there is enough of the page left to be shown).

See fiddle: http://jsfiddle.net/tHXsS/

piatek
  • 376
  • 1
  • 6
  • That's exactally the problem. But your solution is not workable. Bottom margin will show in every case which will look very ugly. – Jawad Sep 02 '12 at 18:07
  • True, but was meant just as an example because your problem depends on the design of the page. There is lots of ways to achieve this, but dictate a layout that extends your example html . For the header to be on top there has to be content to at least fill the window - you can't go further! – piatek Sep 02 '12 at 18:14
  • And that is why I made a comment "It all depends on the height of the content and I seek a solution where the height does not matter. If height is long enough, it will work but not vice versa". – Jawad Sep 02 '12 at 18:15
  • I think using this solution but wrapping it in a scrollabe dig would make a viable option. The marginat the bottom would not be added to tthe pagebut the div. Not perfect, but other options seem overly complex with little bbenefit. +1 – Jeremy A. West Sep 11 '12 at 00:00
2

Solution: http://jsfiddle.net/AdKy9/2/

Add this to your code:

<!-- 
  padding div tag goes AFTER #med_vac
  but BEFORE closing tag of #content
-->
<div id="lowerPadding"></div>

<!-- script tag goes in <head> -->

<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">

  $(document).ready(function() {
    $("a").click(function() {
      var targ = $(this).attr('href');
      var elem = $(targ);
      document.location.href= targ;
      assureAtTop(elem);
      document.location.href= targ;
    });
  });


  function assureAtTop(inObj) {
    var y = $(inObj).height();
    var z = $("#lowerPadding").height();
    var w = $(window).height();
    while (y+z < w) {
      $("#lowerPadding").append("<br/>");
      z = $("#lowerPadding").height();
    }
  }

</script>
  • Gets clicked on <a> element, goes to location.
  • Gets height of target location, padding tag, and window.
  • Adds <br/> tags to the padding tag until target location is at the top of the window

    Note: checks ALL <a> tags because the second or even third target locations might need padding if the window has a large vertical height and/or a large horizontal width. This also could be implemented without jQuery, but using jQuery is just easier and cross-browser.

recursion.ninja
  • 5,377
  • 7
  • 46
  • 78
2

My initial solution to address your problem is similar to @saurabh's above:

http://jsfiddle.net/Cgx3h/

$('.sub_navi a').click(function() {
    var theID = $(this).attr('href');
    $(theID+':last-child').css('min-height', $(window).height());
})

Something else you may consider, if you end up using jQuery, is highlighting the focused content - while dimming the rest...

http://jsfiddle.net/hZGwA/

$('.sub_navi a').click(function() {
    $('#content div').css('opacity',0.5);
    var theID = $(this).attr('href');
    $(theID).css('opacity', 1);
})

Dawson
  • 7,567
  • 1
  • 26
  • 25
2

Here is what i did:

  1. the user scroll down the page.
    nothing unusual happens (there is no change to your page).

  2. the user click/use your anchor.
    the code creates some empty space after #content, so it can place the desired part on top of the screen.

  3. the user scroll the page up to the first div inside #content (could be any point you like) or hit the back button to go to the top of the page.
    the empty space disappears (your page is back to normal).

Test online here: http://jsfiddle.net/RASG/z3q3s/

Or save this code as an HTML file to test it on your pc:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>

<head>
    <script src="http://code.jquery.com/jquery.min.js" type="text/javascript"></script>
    <script>
    $(document).ready(function() {
        function isScrolledIntoView(elem){
            var docViewTop = $(window).scrollTop();
            var docViewBottom = docViewTop + $(window).height();

            var elemTop = $(elem).offset().top;
            var elemBottom = elemTop + $(elem).height();

            return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
        }

        var elem_that_hides_dummydiv = $('#content div:first');
        var elem_that_shows_dummydiv = $('#content div:last');
        $(window).scroll(function() {
            if (isScrolledIntoView(elem_that_hides_dummydiv)) { $('#dummydiv').hide() }
        });
        $('#gonnaclickhere').click(function() {
            $('#dummydiv').css({'height':(elem_that_shows_dummydiv.offset().top)+'px'}).show()
        })
    });
    </script>
</head>

<body>

<ul class="sub_navi">
    <li><a href="#sheds_housing">Sheds &amp; Housing</a></li>
    <li><a href="#feed_fodder">Feed &amp; Fodder</a></li>
    <li id="gonnaclickhere"><a href="#med_vac">Medication &amp; Vaccination</a></li>
</ul>

<div id="content">

    <div id="content_pic">
    <img src="images/cattle/cattle_main.jpg" width="400" height="300" alt="Cattle Main" title="Cattle Main" />
    </div>

    <p>Pak United Food Services Ltd., (PUFS) has earned a creditable name and become a major player in the animal husbandry market by building upon Pakistan&apos;s large livestock population. Introducing the concept of corporate cattle farming on scientific lines, the conglomerate uses a livestock development policy consisting of innovative strategies and action plans with the intention of bringing about a radical change in the current livestock production system. The cattle farms are established on rich and fertile acres of land and consist of an impressive and mixed herd of cows/buffalos and sheep/goats.</p>
    <p>A hybrid meat breed is developed by crossing the local indigenous breeds which are predominately draught/milch animals with high meat yielding animals from other parts of the world. A herd management system is incorporated to improve record keeping and obtain information for bench marking decisions. The farms employ a state of the art feedlot design involving the integration of the standard components into a fully functional operating system. This consists of housing, feeding, watering, health-care and cattle effluent &amp; manure management systems, making them well known across the country.</p>

    <div id="sheds_housing">
    <h1>sheds &amp; housing</h1>
    <img src="images/cattle/sheds_housing.png" width="150" height="150" alt="Sheds & Housing" title="Sheds & Housing" />
    <p>The housing for the animals utilizes a proper lay out for the farm buildings while keeping in view the environment, climate and wind direction. Sheds, pens and paddocks are constructed according to different categories and sex groups besides other infrastructure &amp; allied facilities. All buildings are made airy for the protection of the animals from extreme temperatures and strong winds. Adequate supply of water for drinking and cleaning is made necessary with strict maintenance of hygienic conditions. Ample sunlight and natural ventilation is assured to assist in the reduction of moisture and bacteria, offering a healthier, cleaner &amp; drier environment while also reducing the risk of disease and mortality in the livestock.</p>
    </div>

    <div id="feed_fodder">
    <h1>feed &amp; fodder</h1>
    <img src="images/cattle/feed_fodder.png" width="150" height="150" alt="Feed & Fodder" title="Feed & Fodder" />
    <p>The farms are equipped with in-house feed formulation capabilities which produce feed of constant quality and are palatable, nutritious and free from contamination. Feed supplies are made available according to different feed formulae while keeping in view the nutrient value and energy levels. Daily requirements are worked out for each category and class to achieve improved growth &amp; overall health. A restricted feeding regime is employed that is balanced &amp;amp; concentrated, containing minerals &amp; vitamins, leading to an improved feed/gain ratio. Fodder &amp; wheat/rice straws are purchased/contracted from the nearest markets, while treating it with ammonia or urea to improve the quality and gain a marked effect on cattle weight during the fattening period.</p>
    </div>

    <div id="med_vac">
    <div id="med_vac_title">
    <h1>medication &amp; vaccination</h1>
    </div>
    <img src="images/cattle/med_vac.png" width="150" height="150" alt="Medication & Vaccination" title="Medication & Vaccination" />
    <p>Regular vaccination of the whole herd against contagious and infectious diseases are carried out as a prophylactic measure in order to make sure that the animals are free of diseases of digestive, respiratory, urinary, gynecological and obstetrics by a designated veterinarian. A proactive health plan in employed to improve the health, welfare and productivity of the animals. A pre-weaning vaccination program is used with correct, effective and proper vaccines, dewormers, antibiotics and other medications to prime the immune systems of the animals. Furthermore post-weaning vaccination program is used to boost the immune system of the animals and increase the passive protection against common endemic livestock diseases.</p>
    </div>

</div>

<div id='dummydiv' style="bottom: 0; width: 100%;"></div>

</body>

</html>

Tested with FF13 and IE9.

RASG
  • 5,988
  • 4
  • 26
  • 47
1

You will want to wrap your navigation with another div so that you can apply CSS to the navigation entirety. Once that is done you can then position the header to fixed. Next step is to make room for the constant header at the top of the page by moving the content of the page down some (height of navigation) To do this wrap all your content in another div (don't include navigation in this content div) and apply some CSS - margin-top: (height of nav);

#topnav
{
    position: fixed;
}

#content
{
    margin-top: (height of nav);
}

EDIT:

Ah ok I see what you want. To accomplish this you either set the height of the div's Or use min-height on all the dive that way when you go to the anchor their will be room on the bottom for the browser to scroll down to.

So you'd have to define a new class in your CSS as element or item and add a class to each of the div's

CSS 

.elementItem
{
    //use height or min height
}

HTML

<div id="sheds" class="elementId">
    Content
</div>

See JSFiddle: http://jsfiddle.net/dKfVL/

Nate-Wilkins
  • 5,364
  • 4
  • 46
  • 61
1

Check-out my solution first: http://jsfiddle.net/dKfVL/4/

The above solution uses JavaScript, it adds height to the required div dynamically only when the link is clicked.

var fixLink = $(".sub_navi li:last a"); // change this to a/c to your requirement

fixLink.click(function(){
    var targetDiv = fixLink.attr("href"); //get the ID of div to be fixed
    $(targetDiv).height($(window).height());
});  

This does not remove the height afterwards, I don't see a reason why you would like to do that. But if you really want to do that, you can monitor the scroll-event of the browser if the scroll is greater that the view-port height, then you can set height of the target div to auto.


Option 2:
If you don't want to use javascript, you can use the vhunit of css, which is very similar to % unit in css, with the difference that it is relative to view port, and it currently work in chrome only.

CSS:

#med_vac {
  height: 100vh;
}

jsfiddle: http://jsfiddle.net/dKfVL/5/
Note: this is not cross-browser

Saurabh Kumar
  • 5,576
  • 4
  • 21
  • 30
1

try this fiddle: http://jsfiddle.net/dKfVL/9/

I'm not sure this is possible with css alone (at least not cross-browser anyway).

I've used jQuery to make sure that the #med_vac element has enough height to ensure the title will appear at the top of the page. I've set the code to run when the window is resized so it will also respond to any screen size changes.

Hope this helps!

Tom
  • 224
  • 4
  • 14
1

A better one (No padding div required!)

Try with this jsfiddle. Its working perfectly for me.

Highlights of this fiddle:

  1. No padding div required
  2. Changing height of last wrapper div, only when last link is clicked

Code below.

$(document).ready(function(){
  //apply height change while clicking on last link only
  $("ul.sub_navi li a:last").click(function(){
    var $targ= $($(this).attr("href"));
    if($targ.height() < $(window).height()){
      $targ.css('min-height', $(window).height())
    }
  });
});​
rajukoyilandy
  • 5,341
  • 2
  • 20
  • 31
1

If you don't mind the sections being reorganized to have the clicked on target moved to the top then this could work http://jsfiddle.net/robx/dKfVL/34/

I made it so that the chosen section gets put right under that very first "Cattle". Not sure what that is, but seems like it's meant to stay where it is.

The only viable options I see here are:

  1. Hide them all and show only the clicked (Accordion or tabbed style).
  2. Reorganize by clone, append and removing so that the chosen section gets moved up and pushes down the rest.
  3. Put some ugly large margin at the bottom which is always there (Undesirable for me).
Hope this helps to point you in a better direction.
robx
  • 3,093
  • 2
  • 26
  • 29
1

Here is a more cross-browser and javascript-less solution.

However, it implies you can use an absolute positioning, hence not very friendly with floats and such :

#med_vac {
    position: absolute;    
    height: 100%;
}

Fork of your fiddle demoing this solution :

http://jsfiddle.net/fFL7x/

Pandaiolo
  • 11,165
  • 5
  • 38
  • 70