Question décalage d'une ancre html pour ajuster l'en-tête fixe [dupliquer]


Cette question a déjà une réponse ici:

J'essaie de nettoyer la façon dont mes ancres fonctionnent. J'ai un en-tête qui est fixé en haut de la page, donc quand vous liez une ancre ailleurs dans la page, la page saute pour que l'ancre soit en haut de la page, laissant le contenu derrière l'en-tête fixe (j'espère ça a du sens). J'ai besoin d'un moyen de décaler l'ancre par le 25px de la hauteur de l'en-tête. Je préférerais HTML ou CSS, mais Javascript serait également acceptable.


854
2018-05-24 07:04


origine


Réponses:


Vous pouvez simplement utiliser CSS sans javascript.

Donnez votre ancre une classe:

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

Vous pouvez ensuite positionner l'ancre avec un décalage supérieur ou inférieur à celui où il apparaît réellement sur la page, en en faisant un élément de bloc et en le positionnant relativement. -250px positionnera l'ancre 250px

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

940
2017-11-01 20:09



J'ai trouvé cette solution:

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

Cela ne crée aucune lacune dans le contenu et les liens d'ancrage fonctionne vraiment bien.


279
2017-08-07 09:22



Je cherchais une solution à cela aussi. Dans mon cas c'était plutôt facile.

J'ai un menu de liste avec tous les liens:

<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>

Et en dessous de cela les rubriques où il devrait aller.

<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>

Maintenant parce que j'ai un menu fixe en haut de ma page, je ne peux pas le faire aller à mon tag parce que ce serait derrière le menu.

Au lieu de cela, j'ai mis une balise span à l'intérieur de mon tag avec l'ID approprié.

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

Maintenant, utilisez 2 lignes de CSS pour les positionner correctement.

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

Changez la valeur supérieure pour correspondre à la hauteur de votre en-tête fixe (ou plus). Maintenant, je suppose que cela fonctionnerait aussi avec d'autres éléments.


129
2017-10-30 11:56



Comme il s'agit d'un souci de présentation, une solution CSS pure serait idéale. Cependant, cette question a été posée en 2012, et bien que des solutions de positionnement relatif / marge négative aient été suggérées, ces approches semblent plutôt hacky, créent des problèmes de flux potentiels et ne peuvent pas répondre dynamiquement aux changements dans le DOM / viewport.

Dans cet esprit, je crois que l'utilisation de JavaScript est encore (Février 2017) la meilleure approche. Voici une solution vanilla-JS qui répondra à la fois aux clics d'ancrage et à la résolution du hash de la page en charge (Voir JSFiddle). Modifier le .getFixedOffset() méthode si des calculs dynamiques sont requis. Si vous utilisez jQuery, voici une solution modifiée avec une meilleure délégation d'événements et un défilement fluide.

(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



Solution pure css inspirée par Alexander Savin:

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

Vous pouvez éventuellement ajouter ce qui suit si la cible est toujours hors de l'écran:

  vertical-align: top;

79
2017-12-14 15:45



FWIW cela a fonctionné pour moi:

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

74
2018-06-19 03:44



J'avais fait face à un problème similaire, malheureusement après la mise en œuvre de toutes les solutions ci-dessus, je suis arrivé à la conclusion suivante.

  1. Mes éléments internes avaient une structure CSS fragile et mettant en œuvre une position relative / jeu absolu, brisait complètement le design de la page.
  2. CSS n'est pas mon fort.

J'ai écrit ce simple scrolling js, qui explique le décalage causé par l'en-tête et déplacé le div à environ 125 pixels plus bas. Veuillez l'utiliser comme bon vous semble.

Le HTML

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

Le 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;
      }
    }
});

Voir un mise en œuvre en direct ici.


28
2017-12-02 04:33