DCR
DCR

Reputation: 15700

unable to get fixed anchors working

I'm trying to implement this solution fixed anchors and haven't been able to make it work. Here's what I have so far. Also, with position:fixed the links are appearing on the left when they should be on the right.

.header{
  height:20px;
}

.right{
  float:right;
}

#section1{   
  background-color:blue;
  color:white;
}
#section2{  
  background-color:green;
  color:white;
}
#section3{  
  background-color:purple;
  color:white;
}
.size{
  float:left;
  width:100%;
  height:700px;
}

.anchor{
  display: block;
  height: 20px; /*same height as header*/
  margin-top: -20px; /*same height as header*/ 
  visibility: hidden;
}
<div class='header' style="position: fixed; top: 0;">
   <div class='right' >
     <a  href ='#home'>home</a>
     <a  href ='#about'>about</a>
     <a  href ='#contact'>contact</a>
   </div> 
</div>


<span class='anchor' id='home'></span>
    <div id='section1' class='size'>home
    </div> 
<span class='anchor' id='about'></span>
    <div id='section2' class='size'>about
    </div>
<span class='anchor' id='contact'></span>
    <div id='section3' class='size'>contact
    </div>  

Upvotes: 1

Views: 45

Answers (2)

sheriffderek
sheriffderek

Reputation: 9053

You are mixing methodology a bit here. I would separate the styles into one place instead of some inline - and some in the CSS and some as a helper class such as .right. Your span tags are inline - and can't have block things inside them - your a tags should also be block in this case... Hopefully, my example will show a smooth way to write the markup and CSS. - generally - if you are going to get serious about anchor links... you'll end up using JavaScript to calculate the header height - and add padding to the body so that it can sit on top / without covering up content + also help align the offset from the anchor link for each setting to ensure the padding is visually pleasing based on varying screen sized.

https://jsfiddle.net/sheriffderek/sw5sLker/


markup

<header class='site-header'>

  <nav class='main-navigation'>
    <ul class='item-list'>
      <li class="item">
        <a class='link' href="#one">one</a>
      </li>

      <li class="item">
        <a class='link' href="#two">two</a>
      </li>

       <li class="item">
        <a class='link' href="#three">three</a>
      </li>
    </ul>
  </nav>

</header>


<section class='section one' id='one'>
  <h1>Section one</h1>
</section>

<section class='section two' id='two'>
  <h1>Section two</h1>
</section>

<section class='section three' id='three'>
  <h1>Section three</h1>
</section>


styles

body {
  margin: 0; /* reset */
  padding-top: 50px; 
  /* the size of the header... */
  /* usually done with JavaScript */
}

ul {
  list-style: none;
  margin: 0;
  padding: 0;
} /* reset */

a {
  text-decoration: none;
  color: inherit;
} /* reset */

.site-header {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  background: black;
  color: white;
}

.main-navigation .item-list {
  /* you could use flexbox - or inline-block+text-align - or floats */
  /*  if you use floats - put an overflow hidden here - and floats on the .item */
  /* shown in fiddle */
}

.main-navigation .item {
  display: inline-block;
}

.main-navigation .link {
  display: block; /* give these shape for fingers */
  padding: 1rem;
}

.section {
  min-height: 300px;
  color: black; /* 'all sections' */
  padding: 40px 10px; /* JS may be used here to determine offset */
}

.section.one, .section.three {
  background: lightgray; /* specific named areas */
}


Here is some example JS and another fiddle with that in place for fun.

// query for and cache elements you'll need
var $page = $('html, body');
var $body = $('body');
var headerHeight = $('.site-header').outerHeight();
var $navLink = $('.main-navigation').find('.link');

// some settings for you to change
var scrollSpeed = 500; // in miliseconds... set to 0 if you don't want a visible animation

// add the padding for the body based on the header height
$body.css('padding-top', headerHeight);

// add a click event listener
$navLink.on('click', function() {
    var href = $.attr(this, 'href');
    var anchorPosition = $(href).offset().top;
    var offsetAnchorPosition = anchorPosition - headerHeight;

    $page.animate({
        scrollTop:  offsetAnchorPosition
    }, scrollSpeed, function() {
        window.location.hash = href;
    });

    return false;
});

https://jsfiddle.net/sheriffderek/c7xvpch8/ or https://codepen.io/sheriffderek/pen/zwbYPO/

Upvotes: 1

capcj
capcj

Reputation: 1535

Your problem is in the float in the size class, float is a really complicated parameter that mess a lot of features in the html, avoid him.

    .size{                                                                                                                                                   
      //float:left; remove him
      width:100%;
      height:700px;
    }

PS: You can do clear: both; in the end of sizes to try body bound all content together (it would be a bad design), but I strongly encourage you not use float in this case.

An example to you:

<style>
html,body {
    height: 100%;
}
nav{
    height:20px;
    position: absolute;
    top: 0;
    background: white;
    width: 100%;
    z-index: 999;
}

#section1{
background-color:blue;
color:white;
}
#section2{
background-color:green;
color:white;
}
#section3{
background-color:purple;
color:white;
}
.size{
width:100%;
height:700px;
}

.anchor{
display: block;
height: 20px; /*same height as header*/
margin-top: -20px; /*same height as header*/
visibility: hidden;
}
</style>
<!-- language: lang-html -->

<nav>
    <a  href ='#home'>home</a>
    <a  href ='#about'>about</a>
    <a  href ='#contact'>contact</a>
</nav>


<span class='anchor' id='home'></span>
<div id='section1' class='size'>home
</div>
<span class='anchor' id='about'></span>
<div id='section2' class='size'>about
</div>
<span class='anchor' id='contact'></span>
<div id='section3' class='size'>contact
</div>

<!-- end snippet -->

Look my CodePen

Upvotes: 1

Related Questions