Hash Tag Links, die das Browserfenster nicht überfahren

Avatar of Chris Coyier
Chris Coyier am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Wenn ein Link einen Hash enthält, wie dieser

<a href="#section-two">Section Two</a>

Das Browserfenster scrollt sich (sofort) in eine Position, in der das Element mit der ID „section-two“ sichtbar ist. Es scrollt zur kleinstmöglichen Position, um dieses Element vollständig sichtbar zu machen. Dies geschieht typischerweise durch Scrollen des Fensters nach unten, aber beachten Sie, dass der Browser dies auch tut, wenn ein scrollbarer Elterncontainer horizontal scrollen müsste, um das Element sichtbar zu machen. Ich nenne das „Überfahren“ des Browsers, da das Element bündig mit dem oberen Rand des Browserfensters abschließt.

Dies kann

  • Möglicherweise ästhetisch unansehnlich sein
  • Möglicherweise verwirrend sein (besonders wenn man in einen Bereich mit vielen anderen Überschriften springt)
  • Im Falle einer fest positionierten, oben bleibenden Kopfzeile, äußerst problematisch

Das Problem mit der fest positionierten Kopfzeile ist die größte Gefahr, also nehmen wir das als Beispiel und beheben es.

Update! Verwenden Sie einfach scroll-margin-top

Dies ist genau das, wofür die Eigenschaft scroll-margin-top entwickelt wurde. Wie der Name schon sagt, fügt sie dem Element nach einem Scroll-Ereignis einen oberen Rand hinzu. Wenn wir also zum Beispiel 50px Abstand zwischen der Oberkante des Viewports und dem Element wünschen, können wir Folgendes tun

Aber warten Sie! Wenn Sie auf diesen Ankerlink geklickt haben und nichts passiert ist, liegt das wahrscheinlich daran, dass Sie Safari 11 oder älter (macOS oder iOS) verwenden. Um diese zu unterstützen, müssen wir dies mit scroll-snap-margin-top, einer älteren Version der Eigenschaft, kombinieren.

h2 {
  scroll-margin-top: 50px;
  scroll-snap-margin-top: 50px; /* iOS 11 and older */
}

/* If the browser supports the property... */
@supports (scroll-margin-top: 0;) {
  h2 {
    scroll-margin-top: 50px;
  }
}

Alle anderen behandelten Methoden stammen aus der ursprünglichen Version dieses Artikels, die 2010 veröffentlicht wurde.

Felsenfeste (schmutzige HTML) Methode

Anstatt uns wie üblich zuerst auf den fortschrittlichsten Weg zur Lösung des Problems zu konzentrieren, schauen wir uns den möglichst browserübergreifend kompatiblen Weg an.

Anstatt die ID auf die Kopfzeile zu setzen, setzen wir sie auf ein leeres Span-Tag innerhalb der Kopfzeile. Dies beeinträchtigt das Erscheinungsbild der Kopfzeile überhaupt nicht. Die Verwendung eines Span für eine rein verhaltensbezogene Sache wie diese ist jedoch nicht ideal.

<a href="#goto">Jump</a>

<!-- yadda yadda yadda -->

<h2>
   <span id="goto">   </span>
   Header
</h2>

Dann ziehen wir im CSS den Span über die eigentliche Kopfzeile mit einem negativen oberen Rand nach oben. Anschließend schieben wir die Kopfzeile durch einen positiven unteren Abstand wieder nach unten, um seltsame Layoutprobleme, die durch das Nach-oben-Ziehen verursacht werden, abzumildern.

h2 span { 
  margin-top: -300px; /* Size of fixed header */
  padding-bottom: 300px; 
  display: block; 
}

Idealerweise würden wir den Span einfach absolut über der Kopfzeile positionieren, aber IE7 spielt da nicht gut mit und ignoriert die Sprünge komplett. IE6 hat erhebliche Probleme mit der festen Positionierung, daher ist diese Demo darin fehlerhaft, und wir gehen da nicht weiter darauf ein, obwohl ich sicher bin, dass diese Idee darin im Grunde funktioniert, wenn man das Problem der festen Positionierung beheben kann.

Schönere (saubere HTML) Methode

Die Verwendung des zusätzlichen Spans ist aus zwei Gründen nicht semantisch: (1) Sie verknüpfen den Link direkt mit einem leeren Span, was bedeutungslos ist. (2) Der Span sollte überhaupt nicht da sein. Das HTML sollte lauten

<a href="#goto">Jump</a>

<!-- yadda yadda yadda -->

<h2 id="goto">Header</h2>

Dann lösen wir das Kopfzeilen-/Abstandsproblem, indem wir ein Pseudo-Element verwenden, um die gleiche Aufgabe zu erfüllen, die der Span in unserer schmutzigen HTML-Version hatte. Wir geben ihm eine Höhe, die die Größe der Kopfzeile nach oben verschiebt, und verwenden dann einen negativen Rand, um ihn wieder an seinen Platz zu ziehen.

h2::before { 
  display: block; 
  content: " "; 
  margin-top: -285px; 
  height: 285px; 
  visibility: hidden; 
  pointer-events: none;
}

Mehr von Nicolas Gallagher

Ich habe die ursprüngliche Idee dafür über Forrst gepostet, und Nicolas Gallagher hat sie aufgegriffen und weiterentwickelt, wie Nic es gerne tut =). Er weist darauf hin, dass die Höhen-/Randtechnik problematisch sein kann, wenn man einen Hintergrund auf den Kopfzeilen hat und nicht möchte, dass dieser sich ausdehnt. Er verhindert dies, indem er mit background-clip experimentiert, einen Unterstrich verwendet und anderes. Und große Anerkennung an Ira McMahon für die Anregung der Idee auf Forrst.

Als Teil von Nics Demos verwendet er :target, um die Farbe der Kopfzeile nach „dem Sprung“ zu ändern. Dies ist eine großartige Erinnerung an diesen Pseudo-Selektor und eine perfekte Anwendung dafür. Target stimmt überein, wenn der Hash-Tag in der URL mit der ID eines Elements übereinstimmt. Schnelle Erinnerung: Wenn die URL http://blahblahblah.com/#header-one ist und ein Element wie vorhanden ist.

Was geht ab

dann stimmt dieser Selektor mit h2:target { background: yellow; } überein.

Mehr von Patrick Strietzel

Ich habe herausgefunden, dass das Hash-Tag-Verhalten von IE7 (Ignorieren von padding-top) durch Setzen des Anzeigewerts auf inline-block getrickst werden kann.

h2 { 
  margin-top: -285px; 
  padding-top: 285px; 
  display: inline-block;
}

Natürlich kann eine solche Anzeigeänderung Konsequenzen haben. inline-block ist sehr anders als block, also Vorsicht.

Mehr von Kirk Gleffe

Kirk hat einen Weg gefunden, es nur mit Margin und ein bisschen transition-delay zu tun.

Mehr von Alex Wolfe

Alex schrieb, um zu erwähnen, dass der Abstand auf der Kopfzeile über dem Text darüber liegen könnte. Das bedeutet, dass er Klicks oder Textauswahl blockieren kann. Sie können dies mit z-index beheben, entweder indem Sie Text in etwas mit einem höheren z-index einwickeln oder vielleicht einen negativen z-index auf den Kopfzeilen verwenden.