Frage Offset eines HTML-Ankers zur Anpassung für einen festen Header [Duplizieren]


Diese Frage hat hier bereits eine Antwort:

Ich versuche, die Arbeitsweise meiner Anker zu verbessern. Ich habe eine Kopfzeile, die am oberen Rand der Seite fixiert ist. Wenn Sie also an einer anderen Stelle auf der Seite verlinken, springt die Seite so, dass der Anker oben auf der Seite steht und der Inhalt hinter der festen Kopfzeile bleibt (hoffe ich Das macht Sinn). Ich brauche einen Weg, um den Anker um 25px von der Höhe des Headers zu versetzen. Ich würde HTML oder CSS bevorzugen, aber Javascript wäre auch akzeptabel.


854
2018-05-24 07:04


Ursprung


Antworten:


Sie könnten einfach CSS ohne Javascript verwenden.

Gib deinem Anker eine Klasse:

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

Sie können den Anker dann um einen Abstand höher oder tiefer als auf der Seite positionieren, indem Sie ihn als Blockelement positionieren und relativ positionieren. -250px positioniert den Anker 250px

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

940
2017-11-01 20:09



Ich habe diese Lösung gefunden:

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

Dies schafft keine Lücke im Inhalt und Anker-Links funktionieren wirklich nett.


279
2017-08-07 09:22



Ich habe auch nach einer Lösung gesucht. In meinem Fall war es ziemlich einfach.

Ich habe ein Listenmenü mit allen Links:

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

Und darunter die Überschriften, wohin es gehen soll.

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

Jetzt, da ich ein festes Menü oben auf meiner Seite habe, kann ich es nicht einfach zu meinem Tag bringen, weil das hinter dem Menü wäre.

Stattdessen habe ich ein span-Tag in mein Tag mit der richtigen ID eingefügt.

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

Verwenden Sie jetzt zwei Linien CSS, um sie richtig zu positionieren.

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

Ändern Sie den oberen Wert so, dass er der Höhe Ihres festen Headers (oder mehr) entspricht. Jetzt gehe ich davon aus, dass dies auch mit anderen Elementen funktionieren würde.


129
2017-10-30 11:56



Da dies ein Anliegen der Präsentation ist, wäre eine reine CSS-Lösung ideal. Diese Frage wurde jedoch 2012 gestellt, und obwohl relative Positionierungs- / Negativmargen-Lösungen vorgeschlagen wurden, erscheinen diese Ansätze eher hacky, erzeugen potenzielle Flow-Probleme und können nicht dynamisch auf Änderungen im DOM / Viewport reagieren.

In diesem Sinne glaube ich, dass die Verwendung von JavaScript ist immer noch (Februar 2017) der beste Ansatz. Im Folgenden finden Sie eine Vanilla-JS-Lösung, die sowohl auf das Verankern von Klicks reagiert als auch den Seitenhash beim Laden auflöst (Siehe JSFiddle). Modifiziere den .getFixedOffset() Methode, wenn dynamische Berechnungen erforderlich sind. Wenn Sie jQuery verwenden, Hier ist eine modifizierte Lösung mit besserer Ereignisdelegierung und reibungslosem Scrollen.

(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



Pure CSS-Lösung inspiriert von Alexander Savin:

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

Optional können Sie Folgendes hinzufügen, wenn das Ziel immer noch nicht auf dem Bildschirm angezeigt wird:

  vertical-align: top;

79
2017-12-14 15:45



FWIW das hat bei mir funktioniert:

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

74
2018-06-19 03:44



Ich hatte ein ähnliches Problem, leider kam ich nach der Implementierung aller oben genannten Lösungen zu dem folgenden Ergebnis.

  1. Meine inneren Elemente hatten eine zerbrechliche CSS-Struktur und die Implementierung eines relativen / absoluten Spielstandes unterbrach das Seitendesign vollständig.
  2. CSS ist nicht meine Stärke.

Ich schrieb dieses einfache Scrolling js, das für den Offset verantwortlich ist, der durch den Header verursacht wurde, und verlagerte das div um 125 Pixel darunter. Bitte benutzen Sie es wie Sie es für richtig halten.

Der HTML-Code

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

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

Ein ... sehen Live-Umsetzung hier.


28
2017-12-02 04:33



Sie können es tun, ohne js und ohne HTML zu ändern. Es ist nur CSS.

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

Dadurch wird vor jedem a-Tag mit einer ID ein Pseudo-Element angehängt. Passen Sie die Werte an die Höhe Ihrer Kopfzeile an.


26
2018-06-25 17:04