Header fixed over subtitle by clicking on a content index anchor

Asked

Viewed 64 times

1

I have a fixed header at the top of the page, which calls a index, this index allows you to navigate the text using anchor, the point is that when I click on an item of the index, navigate to the chosen item, but the header is over the item, how can I resolve?

for the header:

<style>
  html { padding: 0; }
  body { padding-top: 40px; /* header height */ }
  #header { position: fixed; top: 0; left: 0; width: 100%; height: 40px;}
</style>

inserir a descrição da imagem aqui

1 answer

1


I adapted an answer from Soen down below.

The code has an explanation, but in short:

  1. When loading the page, check if it has a hash #. Example: site.com/#a. If it is, then we scroll a little above that element;
  2. We’ve got all the elements <a> who own the href starting with #;
  3. We added a Listener at the click of these elements;
  4. When the user clicks on one of these elements <a>, the browser will scroll to the #id and the Listener will make a second scroll for a few pixels above.

// Aqui nós estaremos realizando o scroll da página para 45px acima
// de onde ela está atualmente
function offsetAnchor() {
  if (location.hash.length !== 0) {
    window.scrollTo(window.scrollX, window.scrollY - 45);
  }
}

// Aqui estou adicionando um listener à todos elementos <a> que
// redirecionam para algum link que comece com #. Você pode criar uma 
// classe ou aplicar à elementos específicos.
document.querySelectorAll('a[href^="#"').forEach(el => {
  el.addEventListener("click", function() {
  
    window.setTimeout(function() {
      // O clique é capturado antes da mudança do #, então
      // o timeout faz com que esse código seja executado
      // apenas após a rolagem do redirecionamento ser executada
      offsetAnchor();
    }, 0);

  });
})

// Definimos o offset inicial caso a página aberta já esteja indo para um #elemento
window.setTimeout(offsetAnchor, 0);
header {
  background-color: purple;
  color: white;
  height: 40px;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
}
.anchors {
  margin-top: 45px;
  height: 200px;
}

#a1,
#a2,
#a3 {
  height: 100px;
}

#a1 {
  background-color: #aaa;
}

#a2 {
  background-color: blue;
}

#a3 {
  background-color: red;
  margin-bottom: 300px;
}
<header>
  Header fixo
</header>
<div class="anchors">
  <a href="#a1">Primeiro</a>
  <a href="#a2">Segundo</a>
  <a href="#a3">Terceiro</a>
</div>
<div>
  <p id="a1">Primeiro texto</p>
  <p id="a2">Segundo texto</p>
  <p id="a3">Terceiro texto</p>
</div>

See also Why you sometimes need setTimeout with a value of 0 (zero)?

  • But keep the fixed header above the content?

  • 1

    The fixed header is just the situation of the question, the answer solves the problem even without having it, leaving the example cleaner. But as it’s easier to show than to explain, I edited the answer with the fixed header.

  • @Rafaeltavares, Perfect, Thank you

Browser other questions tagged

You are not signed in. Login or sign up in order to post.