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

Resuelto Matt Dryden asked hace 12 años • 0 respuestas

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, por lo que cuando se vincula a un ancla en otra parte de la página, la página salta para que el ancla esté en la parte superior de la página, dejando el contenido detrás del encabezado fijo (espero eso tiene sentido). Necesito una forma de compensar el ancla en 25 píxeles desde la altura del encabezado. Preferiría HTML o CSS, pero Javascript también sería aceptable.

Matt Dryden avatar May 24 '12 14:05 Matt Dryden
Aceptado

Podrías usar CSS sin ningún javascript.

Dale una clase a tu presentador:

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

Luego puede colocar el ancla un desplazamiento más alto o más bajo de donde realmente aparece en la página, convirtiéndolo en un elemento de bloque y posicionándolo relativamente. -250px posicionará el ancla hacia arriba 250px

a.anchor {
    display: block;
    position: relative;
    top: -250px;
    visibility: hidden;
}
Jan avatar Nov 01 '2012 20:11 Jan

Encontré esta solución:

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

Esto no crea ningún vacío en el contenido y los enlaces ancla funcionan muy bien.

Alexander Savin avatar Aug 07 '2012 09:08 Alexander Savin

FWIW esto funcionó para mí:

[id]::before {
  content: '';
  display: block;
  height:      75px;
  margin-top: -75px;
  visibility: hidden;
}
Mark Nottingham avatar Jun 19 '2014 03:06 Mark Nottingham

Yo también estaba buscando una solución para esto. 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, los títulos a los que debe 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, como tengo un menú fijo en la parte superior de mi página, no puedo simplemente hacer que vaya a mi etiqueta porque estaría detrás del menú.

En su lugar, 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 posicionarlas 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 también funcionaría con otros elementos.

Hrvoje Miljak avatar Oct 30 '2012 11:10 Hrvoje Miljak

Como se trata de una cuestión de presentación, lo ideal sería una solución CSS pura. Sin embargo, esta pregunta se planteó en 2012, y aunque se han sugerido soluciones de posicionamiento relativo/margen negativo, estos enfoques parecen bastante complicados, crean posibles problemas de flujo y no pueden responder dinámicamente a los cambios en el DOM/ventana gráfica.

Con eso en mente, creo que usar JavaScript sigue siendo (febrero de 2017) el mejor enfoque. A continuación se muestra una solución Vanilla-JS que responderá a los clics de anclaje y resolverá el hash de la página al cargar (consulte JSFiddle) . Modifique el .getFixedOffset()método si se requieren cálculos dinámicos. Si está utilizando jQuery, aquí tiene una solución modificada con una mejor delegación de eventos y un desplazamiento fluido .

(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);
Ian Clark avatar Oct 25 '2012 10:10 Ian Clark