html fija El encabezado de página fijo se superpone a los anclajes de página



header css ejemplos (22)

Si bien algunas de las soluciones propuestas funcionan para los enlaces de fragmentos (= enlaces hash) dentro de la misma página (como un enlace de menú que se desplaza hacia abajo), encontré que ninguna de ellas funcionaba en Chrome actual cuando quiere usar enlaces de fragmentos provenientes de otros páginas

Por lo tanto, llamar a www.mydomain.com/page.html#foo desde cero NO compensará su objetivo en Chrome actual con ninguna de las soluciones CSS o las soluciones JS dadas.

También hay un informe de error de jQuery que describe algunos detalles del problema.

SOLUCIÓN

La única opción que encontré hasta ahora que realmente funciona en Chrome es JavaScript que no se llama onDomReady pero con un retraso.

// set timeout onDomReady
$(function() {
    setTimeout(delayedFragmentTargetOffset, 500);
});

// add scroll offset to fragment target (if there is one)
function delayedFragmentTargetOffset(){
    var offset = $(':target').offset();
    if(offset){
        var scrollto = offset.top - 95; // minus fixed header height
        $('html, body').animate({scrollTop:scrollto}, 0);
    }
}

RESUMEN

Sin un retraso JS, las soluciones probablemente funcionarán en Firefox, IE, Safari, pero no en Chrome.

Si tengo un encabezado sin desplazamiento en una página HTML, fijado en la parte superior, con una altura definida:

¿Hay una manera de usar el anclaje de URL (la parte #fragment ) para que el navegador se desplace a un cierto punto de la página, pero respete la altura del elemento fijo sin la ayuda de JavaScript ?

http://foo.com/#bar
WRONG (but the common behavior):         CORRECT:
+---------------------------------+      +---------------------------------+
| BAR///////////////////// header |      | //////////////////////// header |
+---------------------------------+      +---------------------------------+
| Here is the rest of the Text    |      | BAR                             |
| ...                             |      |                                 |
| ...                             |      | Here is the rest of the Text    |
| ...                             |      | ...                             |
+---------------------------------+      +---------------------------------+

Answer #1

Tuve muchos problemas con muchas de las respuestas aquí y en otros lugares, ya que mis anclas marcadas eran encabezados de sección en una página de Preguntas frecuentes, por lo que compensar el encabezado no fue de ayuda, ya que el resto del contenido se quedaría donde estaba. Así que pensé que iba a publicar.

Lo que terminé haciendo fue un compuesto de algunas soluciones:

  1. El CSS:

    .bookmark { margin-top:-120px; padding-bottom:120px; display:block; }

Donde "120px" es la altura fija de su encabezado (quizás más un margen).

  1. El enlace del marcador HTML:

    <a href="#01">What is your FAQ question again?</a>

  2. El contenido marcado HTML:

    <span class="bookmark" id="01"></span> <h3>What is your FAQ question again?</h3> <p>Some FAQ text, followed by ...</p> <p>... some more FAQ text, etc ...</p>

Lo bueno de esta solución es que el elemento span no solo está oculto, sino que está esencialmente colapsado y no elimina su contenido.

No puedo tomar mucho crédito por esta solución, ya que proviene de un conjunto de recursos diferentes, pero funcionó mejor para mí en mi situación.

Puedes ver el resultado real here .


Answer #2

Para mi mente purista, se siente algo intrincado, pero como solución solo para css puede agregar relleno al elemento anclado activo mediante el selector de :target :

html, body {height:100%; min-height:100%; margin:0;}
body {min-height:200%;}
header {display:inline-block; position:fixed; font-size:1.5em; height:100px; top:0; left:0; right:0; line-height:100px; background:black; text-align:center;}
header a {color:#fff;}
section {padding:30px; margin:20px;}
section:first-of-type, section:target {padding-top:130px;}
<header><a href="#one">#One</a> <a href="#two">#two</a> <a href="#three">#three</a></header>
<section id="one"><h1>One</h1>Aenean lacinia bibendum nulla sed consectetur. Nullam id dolor id nibh ultricies vehicula ut id elit. Integer posuere erat a ante venenatis dapibus posuere velit aliquet.</section>
<section id="two"><h1>Two</h1>Aenean lacinia bibendum nulla sed consectetur. Nullam id dolor id nibh ultricies vehicula ut id elit. Integer posuere erat a ante venenatis dapibus posuere velit aliquet.</section>
<section id="three"><h1>Three</h1>Aenean lacinia bibendum nulla sed consectetur. Nullam id dolor id nibh ultricies vehicula ut id elit. Integer posuere erat a ante venenatis dapibus posuere velit aliquet.</section>


Answer #3

Yo tuve el mismo problema. Lo resolví agregando una clase al elemento delimitador con la altura de la barra superior como el valor de relleno superior.

<h1><a class="anchor" name="barlink">Bar</a></h1>

Y luego simplemente el css:

.anchor { padding-top: 90px; }

Answer #4

Si no puede o no quiere establecer una nueva clase, agregue una altura fija ::before pseudo-elemento a la pseudo-clase :target en CSS:

:target::before {
  content: "";
  display: block;
  height: 60px; /* fixed header height*/
  margin: -60px 0 0; /* negative fixed header height */
}

O desplácese por la página relativa a :target con jQuery:

var offset = $(':target').offset();
var scrollto = offset.top - 60; // minus fixed header height
$('html, body').animate({scrollTop:scrollto}, 0);

Answer #5

Esto funciona para mi:

ENLACE HTML para anclar:

<a href="#security">SECURITY</a>

Ancla HTML:

<a name="security" class="anchor"></a>

CSS:

.anchor::before {
    content: "";
    display: block;
    margin-top: -50px;
    position: absolute;
}

Answer #6

No tuve suerte con la respuesta mencionada anteriormente y terminé usando esta solución que funcionó perfectamente ...

Cree un espacio en blanco donde desee establecer su ancla.

<span class="anchor" id="section1"></span>
<div class="section"></div>

Y aplicar la siguiente clase:

  .anchor{
  display: block;
  height: 115px; /*same height as header*/
  margin-top: -115px; /*same height as header*/
  visibility: hidden;
}

¡Esta solución funcionará incluso si las secciones tienen fondos de diferentes colores! Encontré la solución en este enlace.


Answer #7

Aquí hay una solución jquery completa que funcionará en IE:

Supongamos que los elementos de la barra de navegación son algo así:

<ul>
    <li><a class="navigation" href="/#contact-us">Contact us</a></li>
    <li><a class="navigation" href="/#about-us">About us</a></li>
</ul>

Puede usar el siguiente fragmento de jquery para desplazar el desplazamiento:

$(function() {
    $("a.navigation").click(function(event) {
        event.preventDefault();
        offSetScroll($(this));
    });
    offSetScrollFromLocation(window.location.href.toLowerCase());
});

function offSetScroll(anchor) {
    var href = anchor.attr("href");
    offSetScrollFromLocation(href);
}

function offSetScrollFromLocation(href) {
    //Change this according to the height of the navigation bar
    var fromTop = 250;
    if(href.indexOf("#")<=0)
        return;
    var hash=href.substring(href.indexOf("#"));
    var targetOffset = $(hash).offset().top-fromTop;
    $('html, body').animate({scrollTop: targetOffset}, 400, function(e) {

    });
}

Answer #8

Utilizo este método porque, por alguna razón, ninguna de las otras soluciones propuestas realmente funcionó para mí. Prometo que lo intenté.

section {
   position: relative;
   border-top: 52px solid transparent; /* navbar height +2 */
   margin: -30px 0 0;
   -webkit-background-clip: padding-box;
   -moz-background-clip: padding;
   background-clip: padding-box;
}

section:before {
   content: "";
   position: absolute;
   top: -2px;
   left: 0;
   right: 0;
   border-top: 2px solid transparent;
}

Reemplace la sección por una clase si lo prefiere.

fuente: http://nicolasgallagher.com/jump-links-and-viewport-positioning/

  • Probado en Firefox 45 y Chrome 52.
  • versión de arranque: 3.3.7

Para aquellos que no me creen, preparé amablemente un jsfiddle con la solución: SOLUTION


Answer #9

Puedes hacer esto con jQuery:

var offset = $('.target').offset();
var scrollto = offset.top - 50; // fixed_top_bar_height = 50px
$('html, body').animate({scrollTop:scrollto}, 0);

Answer #10
// handle hashes when page loads
// <http://.com/a/29853395>
function adjustAnchor() {
  const $anchor = $(':target');
  const fixedElementHeight = $('.navbar-fixed-top').outerHeight();
  if ($anchor.length > 0)
    window.scrollTo(0, $anchor.offset().top - fixedElementHeight);
}
$(window).on('hashchange load', adjustAnchor);
$('body').on('click', "a[href^='#']", function (ev) {
  if (window.location.hash === $(this).attr('href')) {
    ev.preventDefault();
    adjustAnchor();
  }
});

Answer #11

Estoy usando la respuesta de @ Jpsy, pero por razones de rendimiento, solo estoy configurando el temporizador si el hash está presente en la URL.

$(function() {
      // Only set the timer if you have a hash
      if(window.location.hash) {
        setTimeout(delayedFragmentTargetOffset, 500);
      }
  });

function delayedFragmentTargetOffset(){
      var offset = $(':target').offset();
      if(offset){
          var scrollto = offset.top - 80; // minus fixed header height
          $('html, body').animate({scrollTop:scrollto}, 0);
          $(':target').highlight();
      }
  };

Answer #12

Un enfoque mínimamente intrusivo usando jQuery:

Enlazar:

<a href="#my-anchor-1" class="anchor-link">Go To Anchor 1</a>

Contenido:

<h3 id="my-anchor-1">Here is Anchor 1</a>

Guión:

$(".anchor-link").click(function() {
    var headerHeight = 120;
    $('html, body').stop(true, true).animate({
        scrollTop: $(this.hash).offset().top - headerHeight
    }, 750);
    return false;
});

Al asignar la clase de enlace de anclaje a los enlaces, el comportamiento de otros enlaces (como el acordeón o los controles de pestañas) no se ve afectado.

La pregunta no quiere javascript, pero la otra pregunta más popular está cerrada debido a esta y no pude responder allí.


Answer #13

La mejor manera que encontré para manejar este problema es (reemplace 65px con la altura fija de su elemento):

div:target {
  padding-top: 65px; 
  margin-top: -65px;
}

Si no te gusta usar el selector de target , también puedes hacerlo de esta manera:

.my-target {
    padding-top: 65px;
    margin-top: -65px;
}

Nota: este ejemplo no funcionará si el elemento de destino tiene un color de fondo que difiere de su elemento primario. por ejemplo:

<div style="background-color:red;height:100px;"></div>
<div class="my-target" style="background-color:green;height:100px;"></div>

en este caso, el color verde del elemento my-target sobrescribirá su elemento rojo primario en 65px. No encontré ninguna solución CSS pura para manejar este problema, pero si no tiene otro color de fondo, esta solución es la mejor.


Answer #14
<div style="position:relative; top:-45px;">
    <a name="fragment"> </a>
</div>

Este código debería hacer el truco. Cambie 45px por la altura de la barra de encabezado.

EDITAR: si usar jQuery es una opción, también he tenido éxito al usar jQuery.localScroll con un valor de compensación establecido. La opción de desplazamiento es una parte de jQuery.scrollTo, en la que se basa jQuery.localScroll. Una demostración está disponible aquí: http://demos.flesler.com/jquery/scrollTo/ (segunda ventana, debajo de 'offset')


Answer #15

Lo tengo funcionando fácilmente con CSS y HTML, usando el método "ancla: antes" mencionado anteriormente. Creo que funciona mejor, porque no crea un relleno masivo entre tus divs.

.anchor:before {
  content:"";
  display:block;
  height:60px; /* fixed header height*/
  margin:-60px 0 0; /* negative fixed header height */
}

Parece que no funciona para el primer div en la página, pero puedes contrarrestar eso agregando el relleno a ese primer div.

#anchor-one{padding-top: 60px;}

Aquí hay un violín que funciona: http://jsfiddle.net/FRpHE/24/


Answer #16

Así es como lo conseguí para finalmente ir al lugar adecuado cuando haces clic en la navegación. He añadido un controlador de eventos para los clics de navegación. Luego puedes usar "scrollBy" para subir en el offset.

var offset = 90;

 $('.navbar li a').click(function(event) {
    event.preventDefault();
    $($(this).attr('href'))[0].scrollIntoView();
    scrollBy(0, -offset);
 });

Answer #17

Respuesta oficial adoptada por Bootstrap:

*[id]:before { 
  display: block; 
  content: " "; 
  margin-top: -75px; // Set the Appropriate Height
  height: 75px; // Set the Appropriate Height
  visibility: hidden; 
}

Credits

Merge


Answer #18

La forma en que encuentro ser el más limpio es el siguiente:

  #bar::before {
    display: block;
    content: " ";
    margin-top: -150px;
    height: 150px;
    visibility: hidden;
    pointer-events: none;
  }

Answer #19

Yo uso este enfoque:

/* add class="jumptarget" to all targets. */

.jumptarget::before {
  content:"";
  display:block;
  height:50px; /* fixed header height*/
  margin:-50px 0 0; /* negative fixed header height */
}

Agrega un elemento invisible antes de cada objetivo. Funciona IE8 +.

Aquí hay más soluciones: http://nicolasgallagher.com/jump-links-and-viewport-positioning/


Answer #20

Una respuesta CSS muy simple es poner esto en la parte superior de su hoja de estilos:

a{padding-top: 90px;}
a:link{padding-top: unset;}

El primer estilo regula todas las etiquetas de anclaje donde los segundos estilos anclan las etiquetas con un hipervínculo.

Nota: Esto funciona actualmente en Firefox y Edge, pero tampoco en Chrome.


Answer #21

Implementado utilizando :before funcionó muy bien hasta que nos dimos cuenta de que el pseudo elemento en realidad estaba cubriendo y bloqueando los eventos de puntero que se encontraban dentro del área del pseudo elemento. Usar algo como pointer-events: none en el :before o incluso directamente en el ancla no tuvo ningún efecto.

Lo que terminamos haciendo fue hacer que el anclaje fuera absoluto y luego ajustar su posición para que fuera la distancia / altura del área fija.

Anclaje compensado sin bloqueo de eventos de puntero

.section-marker {

    position: absolute;
    top: -300px;
}

El valor con esto es que no estamos bloqueando ningún elemento que pueda caer dentro de esos 300px. El inconveniente es que al tomar la posición de ese elemento de Javascript se debe tener en cuenta ese desplazamiento, por lo que cualquier lógica tenía que ser ajustada.





fragment