Pregunta compensar un ancla html para ajustar el encabezado fijo [duplicado]


Esta pregunta ya tiene una respuesta aquí:

Estoy tratando de limpiar la forma en que funcionan mis anclajes. Tengo un encabezado que está fijo en la parte superior de la página, así que cuando se vincula a un anclaje en otra parte de la página, la página salta de modo que el anclaje está en la parte superior de la página, dejando el contenido detrás del encabezado fijo (espero eso tiene sentido). Necesito una manera de compensar el ancla por 25px desde la altura del encabezado. Preferiría HTML o CSS, pero Javascript también sería aceptable.


854
2018-05-24 07:04


origen


Respuestas:


Podrías simplemente usar CSS sin ningún javascript.

Dale a tu ancla una clase:

<a class="anchor" id="top"></a>

A continuación, puede colocar el anclaje un desplazamiento más alto o más bajo que donde realmente aparece en la página, convirtiéndolo en un elemento de bloque y posicionándolo relativamente. -250px posicionará el ancla hasta 250px

a.anchor {
    display: block;
    position: relative;
    top: -250px;
    visibility: hidden;
}

940
2017-11-01 20:09



Encontré esta solución:

<a name="myanchor">
    <h1 style="padding-top: 40px; margin-top: -40px;">My anchor</h1>
</a>

Esto no crea ningún espacio en el contenido y los enlaces de anclaje funcionan muy bien.


279
2017-08-07 09:22



Estaba buscando una solución a esto también. En mi caso, fue bastante fácil.

Tengo un menú de lista con todos los enlaces:

<ul>
<li><a href="#one">one</a></li>
<li><a href="#two">two</a></li>
<li><a href="#three">three</a></li>
<li><a href="#four">four</a></li>
</ul>

Y debajo de eso, los títulos a donde debería ir.

<h3>one</h3>
<p>text here</p>

<h3>two</h3>
<p>text here</p>

<h3>three</h3>
<p>text here</p>

<h3>four</h3>
<p>text here</p>

Ahora, porque tengo un menú fijo en la parte superior de la página, no puedo hacer que vaya a mi etiqueta porque eso estaría detrás del menú.

En cambio, puse una etiqueta span dentro de mi etiqueta con la identificación adecuada.

<h3><span id="one"></span>one</h3>

Ahora usa 2 líneas de CSS para ubicarlas correctamente.

h3{ position:relative; }
h3 span{ position:absolute; top:-200px;}

Cambie el valor superior para que coincida con la altura de su encabezado fijo (o más). Ahora supongo que esto funcionaría con otros elementos también.


129
2017-10-30 11:56



Como esta es una preocupación de la presentación, una solución pura de CSS sería ideal. Sin embargo, esta pregunta se planteó en 2012, y aunque se han sugerido soluciones de posicionamiento relativo / margen negativo, estos enfoques parecen bastante extravagantes, crean problemas de flujo potencial y no pueden responder dinámicamente a los cambios en el DOM / viewport.

Con eso en mente, creo que usar JavaScript es todavía (Febrero de 2017) el mejor enfoque. A continuación se muestra una solución vanilla-JS que responderá tanto a los clics de anclaje como a la resolución del hash de la página al cargar (Ver JSFiddle). Modificar el .getFixedOffset() método si se requieren cálculos dinámicos. Si usas jQuery, Aquí hay una solución modificada con una mejor delegación de eventos y un desplazamiento suave.

(function(document, history, location) {
  var HISTORY_SUPPORT = !!(history && history.pushState);

  var anchorScrolls = {
    ANCHOR_REGEX: /^#[^ ]+$/,
    OFFSET_HEIGHT_PX: 50,

    /**
     * Establish events, and fix initial scroll position if a hash is provided.
     */
    init: function() {
      this.scrollToCurrent();
      window.addEventListener('hashchange', this.scrollToCurrent.bind(this));
      document.body.addEventListener('click', this.delegateAnchors.bind(this));
    },

    /**
     * Return the offset amount to deduct from the normal scroll position.
     * Modify as appropriate to allow for dynamic calculations
     */
    getFixedOffset: function() {
      return this.OFFSET_HEIGHT_PX;
    },

    /**
     * If the provided href is an anchor which resolves to an element on the
     * page, scroll to it.
     * @param  {String} href
     * @return {Boolean} - Was the href an anchor.
     */
    scrollIfAnchor: function(href, pushToHistory) {
      var match, rect, anchorOffset;

      if(!this.ANCHOR_REGEX.test(href)) {
        return false;
      }

      match = document.getElementById(href.slice(1));

      if(match) {
        rect = match.getBoundingClientRect();
        anchorOffset = window.pageYOffset + rect.top - this.getFixedOffset();
        window.scrollTo(window.pageXOffset, anchorOffset);

        // Add the state to history as-per normal anchor links
        if(HISTORY_SUPPORT && pushToHistory) {
          history.pushState({}, document.title, location.pathname + href);
        }
      }

      return !!match;
    },

    /**
     * Attempt to scroll to the current location's hash.
     */
    scrollToCurrent: function() {
      this.scrollIfAnchor(window.location.hash);
    },

    /**
     * If the click event's target was an anchor, fix the scroll position.
     */
    delegateAnchors: function(e) {
      var elem = e.target;

      if(
        elem.nodeName === 'A' &&
        this.scrollIfAnchor(elem.getAttribute('href'), true)
      ) {
        e.preventDefault();
      }
    }
  };

  window.addEventListener(
    'DOMContentLoaded', anchorScrolls.init.bind(anchorScrolls)
  );
})(window.document, window.history, window.location);

129
2017-10-25 10:53



Solución de CSS pura inspirada por Alexander Savin:

a[name] {
  padding-top: 40px;
  margin-top: -40px;
  display: inline-block; /* required for webkit browsers */
}

Opcionalmente, puede agregar lo siguiente si el objetivo aún está fuera de la pantalla:

  vertical-align: top;

79
2017-12-14 15:45



FWIW esto funcionó para mí:

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

74
2018-06-19 03:44



He estado enfrentando un problema similar, lamentablemente después de implementar todas las soluciones anteriores, llegué a la siguiente conclusión.

  1. Mis elementos internos tenían una estructura de CSS frágil y la implementación de una posición relativa / juego absoluto, estaba rompiendo completamente el diseño de la página.
  2. CSS no es mi fuerte.

Escribí este desplazamiento simple js, que explica el desplazamiento causado por el encabezado y reubicó el div alrededor de 125 píxeles a continuación. Por favor, úsalo como mejor te parezca.

El HTML

<div id="#anchor"></div> <!-- #anchor here is the anchor tag which is on your URL -->

El JavaScript

 $(function() {
  $('a[href*=#]:not([href=#])').click(function() {
    if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') 
&& location.hostname == this.hostname) {

      var target = $(this.hash);
      target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
      if (target.length) {
        $('html,body').animate({
          scrollTop: target.offset().top - 125 //offsets for fixed header
        }, 1000);
        return false;
      }
    }
  });
  //Executed on page load with URL containing an anchor tag.
  if($(location.href.split("#")[1])) {
      var target = $('#'+location.href.split("#")[1]);
      if (target.length) {
        $('html,body').animate({
          scrollTop: target.offset().top - 125 //offset height of header here too.
        }, 1000);
        return false;
      }
    }
});

Ver un implementación en vivo aquí.


28
2017-12-02 04:33



Puedes hacerlo sin js y sin alterar html. Es solo CSS.

a[id]:before {
    content:"";
    display:block;
    height:50px;
    margin:-30px 0 0;
}

Eso agregará un pseudo-elemento antes de cada una de las etiquetas con una identificación. Ajuste los valores para que coincidan con la altura de su encabezado.


26
2018-06-25 17:04



Esto toma muchos elementos de las respuestas anteriores y se combina en una función jQuery anónima minúscula (194 bytes). Ajustar fixedElementHeight para la altura de su menú o elemento de bloqueo.

    (function($, window) {
        var adjustAnchor = function() {

            var $anchor = $(':target'),
                    fixedElementHeight = 100;

            if ($anchor.length > 0) {

                $('html, body')
                    .stop()
                    .animate({
                        scrollTop: $anchor.offset().top - fixedElementHeight
                    }, 200);

            }

        };

        $(window).on('hashchange load', function() {
            adjustAnchor();
        });

    })(jQuery, window);

Si no te gusta la animación, reemplaza

$('html, body')
     .stop()
     .animate({
         scrollTop: $anchor.offset().top - fixedElementHeight
     }, 200);

con:

window.scrollTo(0, $anchor.offset().top - fixedElementHeight);

Versión Uglified:

 !function(o,n){var t=function(){var n=o(":target"),t=100;n.length>0&&o("html, body").stop().animate({scrollTop:n.offset().top-t},200)};o(n).on("hashchange load",function(){t()})}(jQuery,window);

26
2018-04-24 17:02



Para navegadores modernos, simplemente agregue el CSS3: selector de destino a la página. Esto se aplicará a todos los anclajes de forma automática.

:target {
    display: block;    
    position: relative;     
    top: -100px;
    visibility: hidden;
}

24
2018-02-11 16:13