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 aufinline-blockgetrickst 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.
Wow – Ich mache seit 1994 Webentwicklung und irgendwie wusste ich nie, dass man den gehashten Anker auf etwas anderes als einen benannten Anker zeigen kann.
Ich habe immer gemacht
Nun, Lance,
dann hast du nicht wirklich Webentwicklung, sondern Web „Design“ gemacht, glaube ich.
und ja, es gibt einen Unterschied, und ja, das musst du als „Entwickler“ wissen ;)
Bitte nimm es nicht persönlich, aber es ist einfach so.
Tatsächlich mache ich „Entwicklung“ (d. h. Daten und Algorithmen), kein Design – daher meine mittelmäßige Vertrautheit mit den Feinheiten von HTML.
Du solltest das auch ohne Pseudo-Elemente hinbekommen. Ich glaube, das sollte funktionieren
h2 {margin-top: -285px; padding-top: 285px;}
Ich kann es atm nicht in IE7 und darunter ausprobieren. Solange du keine Hintergründe/Hintergrundbilder auf den Überschriften hast, sollte es in Ordnung sein.
@Lance
Heiliger Bimbam! Ich dachte genau das Gleiche! Deshalb war ich beim Lesen etwas verwirrt. Ich brenne darauf, zu einigen alten Seiten zurückzukehren und diesen Teil neu zu gestalten…
Für diejenigen unter euch, die nicht wussten, dass Anker-Tags auf die ID jedes Elements verlinkt werden können, empfehle ich, http://www.w3.org/TR/html401/struct/links.html#h-12.2.3 zu lesen.
Und wenn es darum geht, diese Art von Links optisch ansprechender zu gestalten, verwende ich gerne Ariel Fleslers jQuery.ScrollTo-Plugin http://flesler.blogspot.com/2007/10/jqueryscrollto.html. Es ist schon lange da und gut gemacht.
Das ist, was ich benutze. Liebe das Plugin, weil es dem Benutzer einen visuellen Hinweis gibt, wohin er geht; dass er noch auf derselben Seite ist.
Ich habe das schon immer so gemacht
<a name="someheading"></a>
<h2>Some Heading</h2>
Ich glaube nicht, dass es semantischer ist als dein typischer (nicht-kontextbezogener) Hyperlink, und es umgeht die CSS-Probleme vollständig.
In der aktuellen HTML5-Spezifikation ist die Verwendung des Attributs ‚name‘ in einem Anker ungültig.
Darüber hinaus umgeht es das Problem überhaupt nicht vollständig. Sie müssen den Anker immer noch oberhalb der Überschrift positionieren, ohne den visuellen Fluss des Dokuments zu beeinträchtigen. Das bedeutet, Attributselektoren zu verwenden (nicht von älteren Versionen von IE unterstützt) oder den Ankern eine Klasse/ID hinzuzufügen.
Entschuldigung, ich meinte ID statt Name. Und ja, es wäre etwas Styling nötig, um ihm Höhe zu geben. Was ich „umgehen“ wollte, war das ganze Hoch- und Runterziehen.
Nachdem ich mir jedoch Chris‘ Demos angesehen habe, glaube ich, dass ich den Sinn dieser Übungen verpasst habe (ich habe mir zuerst nur deine Demos angesehen, und Chris‘ hat ein riesiges rotes Banner, das die Komplikationen, die diese Methoden zu lösen versuchen, wirklich veranschaulicht).
Normalerweise habe ich Hash-Links, bei denen das Layout der Webseite solche Probleme nicht verursacht. Zusätzliche 2em Leerraum stören mich nicht (typischerweise wäre ein Hash-Link zwischen Hauptabschnitten, sodass zusätzlicher Raum angemessen wäre). Wenn ich jedoch etwas anderes umgehen muss (wie das riesige Banner, ein Foto oder eine Kommentarbox oder etwas Ähnliches), dann wäre das keine angemessene Lösung.
Wow, das ist interessant. Ich habe dieses Konzept kürzlich implementiert (mit „schmutzigem HTML“ in dieser Seite, die ich für einen befreundeten Designer programmiert habe.
Sie werden sehen, dass sie die fest positionierte Kopfzeile hat und das jQuery scrollTo-Plugin verwendet. Ich hatte es in fast jedem Browser genau gleich zum Laufen gebracht, ohne zusätzliche HTML-Elemente – aber IE7 kollabierte immer den Rand, wenn einer der Links geklickt wurde. Ich habe dieses Verhalten schon einmal bei IE7 gesehen, aber nichts schien es zu beheben, auch nicht das Geben des Elements Layout und dergleichen. Ich habe sogar versucht, die Rand-Einstellungen über JavaScript neu anzuwenden. (Für IE6 ist die Kopfzeile nicht fixiert, sie scrollt normal)
Daher musste ich zum Hinzufügen des zusätzlichen Elements greifen, um negative Ränder zu vermeiden. Ich denke, die Pseudo-Element-Lösung ist eine großartige Option, aber ich frage mich, ob dasselbe Problem mit den Rändern in IE7 auftreten würde. Es wäre lohnenswert, das zu untersuchen.
Ich habe fast vergessen – das :before Pseudo-Element wird in IE7 nicht unterstützt, daher würde die letzte Option nicht funktionieren, wenn IE7-Unterstützung benötigt wird.
Beim erneuten Betrachten habe ich festgestellt, dass du das Span-Element anders verwendest, als ich zuerst verstanden habe.
Hier ist eine Lösung mit sauberem HTML, die in jedem Browser außer IE6 funktioniert
http://www.impressivewebs.com/bump.html
Die wichtigsten Änderungen sind IDs auf den Überschriften, die dann den Rand-/Abstand-Trick erhalten. Und es gibt einen negativen Rand auf dem Navigationsbereich und einen oberen Abstand auf dem Seiten-Wrapper, um die Dinge zu begradigen.
CSS-mäßig ist es nicht die sauberste Lösung, aber für die browserübergreifende Kompatibilität halte ich es für akzeptabel, und der Markup ist sauber.
Ich bin mir immer noch nicht sicher, warum meine Live-Kundenversion in IE7 nicht funktionierte, denn das ist ziemlich genau das, was ich getan habe, und das funktioniert in IE7.
Hallo Louis, in meinem Artikel (verlinkt in Chris‘ Artikel) behandle ich diese Technik. Das Problem tritt auf, wenn man eine Hintergrundfarbe oder ein Bild auf das Ziel-Element setzen möchte und auch Padding-Top verwenden möchte. Die Lösung ist die Verwendung von border-top und background-clip (Methode E).
Ja, danke für den Hinweis. Ich habe mir deine Seiten erst jetzt angesehen. Aber ich denke, die Notwendigkeit von Hintergründen wäre unwahrscheinlich und kann entsprechend behandelt werden.
Die einzige IE-Version, die background-clip unterstützt, ist IE9 Beta. Die einzige reale, browserübergreifende Lösung für dieses Problem ist also Chris' „schmutzige HTML“-Methode oder die ähnliche, die ich oben demonstriert habe.
Aber es ist großartig zu wissen, was möglich sein wird, wenn ältere Versionen von IE aus dem Verkehr gezogen werden. Nur noch nicht sehr praktikabel bis dahin.
Als leichte Ergänzung zu meinem vorherigen Beitrag. Dies scheint eine mögliche Lösung zu sein
h2 {margin-top: -285px; border-top: 285px solid #same-as-background; background: url(“bg.jpg”);}
Kein Pseudo-Element, keine Maskierung (es sei denn, deine Überschrift liegt über einem Container mit einem Hintergrundbild).
Ja Anders, natürlich, aber dann, wenn du ein sich wiederholendes Bild als Teil des Hintergrunds des Elternelements hast, funktioniert die Randfarbenmethode nicht.
Es ist gut.
Ich bin immer mit dem Folgenden gegangen, um zu diesem Ort zu gelangen.
<a name=”top”>Ankerposition</a>
<a href=”#top” >Oben</a>
-vara
wie wäre es damit
<a href="#section">Springen</a>
<h2 id="section" style="padding-top:50px">Überschrift</h2>
Schöne Beispiele für Hash-Tag-Links für das Scrollen auf der Seite. LT
Ich habe eine fest positionierte Kopfzeile von 70px Höhe. Durch Spielen mit den Werten konnte ich dies in Chrome zum Laufen bringen. Gibt es eine Lösung, die in IE 10 funktioniert? Hier ist mein CSS-Snippet
h2
{
font-family:Georgia, „Times New Roman“, Times, serif;
color:#306;
}
h2:before {
Inhalt: ” “;
margin-top: -175px;
height: 175px;
visibility: hidden;
display: block;
display: inline-block;
}
Was ist, wenn die Div, zu der du scrollen möchtest, in mehreren anderen Divs verschachtelt ist? Zum Beispiel mit Bootstrap mit Zeilen- und Spaltenklassen und dem Versuch, zu einer bestimmten Spalte mit Inhalt zu scrollen.
Ich habe dasselbe Problem mit Dreamweaver-Registerkarten-Panels.
Schon wieder hast du mir geholfen, mein Problem schnell zu lösen! Vielen Dank.
Ich habe einen Hintergrund auf meinem
<div id="goto" class="section"></div>, welche Korrektur kann ich verwenden, um einen großen Abstand vor dem Beginn des Inhalts dieser Div zu vermeiden (in einem Einseitenlayout)?Ich dachte, das zu lösende Problem benötige etwas JavaScript. Aber du kommst mit einer saubereren CSS-Methode h2:before. Vielen Dank fürs Teilen.
Wie kann ich verhindern, dass sich die URL im Browser mit dem Hashtag aktualisiert?
Ich weiß, dass es mit JavaScript oder jQuery einen Weg gibt, aber ich finde ihn nicht. Danke
Es könnte nützlich sein, dies zur felsenfeste (schmutzige HTML)-Methode hinzuzufügen
h2 span {
margin-top: -300px; /* Größe der festen Kopfzeile */
padding-bottom: 300px;
display: block;
font-size:1px;
line-height:1px;
}
Ich frage mich, ob es eine Möglichkeit gibt, dies zu tun, ohne die Pixel für Höhe und oberen Rand hart kodieren zu müssen? Ich habe dies in einem meiner Projekte verwendet, und wenn Sie die Größe des Browserfensters ändern, funktioniert es nicht richtig.
Stell dir vor, ich schaue mir eine Seite auf meiner Website an, auf der ich nach unten gescrollt bin,
und ich klicke auf einen Link auf dieser Seite, der mich zu einer Seite springen lässt, die eine exakte Kopie der ersten Seite ist.
Jetzt kann ich dank des obigen Codes an bestimmten Punkten auf dieser Kopie landen, danke fürs Teilen,
aber hier ist der Gehirn-Verdreher: wie springe ich zur EXAKTEN GLEICHEN POSITION, an der ich jetzt gescrollt habe.
Zum Beispiel, stellen Sie sich vor, ich habe 120 Pixel nach unten auf der Seite gescrollt, wie springe ich zu einer Kopie dieser Seite, die genau 120 Pixel nach unten auf der Seite ist.
Es scheinen 2 Anweisungen nötig zu sein: „#1 – bemerken, wie viele Pixel die Person derzeit gescrollt hat“, und „#2 – springen zu einer Kopie dieser Seite AN DER EXAKTEN GLEICHEN Scroll-Position.“
Ich würde mich über Hilfe dabei freuen und werde demjenigen, der zuerst den funktionierenden Code postet, dankbar 20 US-Dollar per Post schicken.
Nochmals vielen Dank.
(PS – nur für den Fall, dass Sie sich fragen: Es gibt einen rationalen Grund, zu einer Kopie der aktuellen Seite springen zu wollen. Stellen Sie sich vor, Sie haben ein nicht abspielendes Video auf der ersten Seite. Wenn jemand darauf klickt, springen wir zu einer Kopie der Seite, auf der dasselbe Video sitzt, aber auf dieser Kopie der Seite beginnt das Video automatisch. Dann, wenn man ein wenig weiter nach unten scrollt, gibt es ein zweites Video auf dieser Kopie der Seite, und wenn wir darauf klicken, springen wir zu einer anderen Kopie derselben Seite, auf der das erste Video nicht abgespielt wird, während das zweite Video abgespielt wird.)
Deshalb verwende ich diese Kopie-Seiten, um das automatische Abspielen zu ermöglichen, WÄHREND ich allen anderen Videos sage, dass sie aufhören sollen abzuspielen.
Also, auch hier, wenn jemand eine bessere funktionierende Code-Idee hat, die das Ziel erreichen kann, „auf ein Video zu klicken, das Video zu starten und gleichzeitig allen anderen abspielenden Videos zu sagen, dass sie AUFHÖREN sollen abzuspielen“. Das wäre die sauberere Lösung.
Daher würde ich mich für eine der beiden oben genannten Anfragen über Hilfe freuen und demjenigen, der zuerst den funktionierenden Code postet, dankbar 20 US-Dollar per Post schicken.
Danke. :-)
Diese Demo ist großartig, danke für Ihre Zeit bei der Erstellung. Gäbe es eine einfache Möglichkeit, sie so zu modifizieren, dass sie für eine Menüleiste am oberen Bildschirmrand angepasst wird? Wenn ich zum „nächsten“ Anker klicke, wird der Titel meines Abschnittsinhalts von meiner Menüleiste verdeckt.
Danke für alle Ideen dazu.
David
Ich wollte nur ein großes DANKESCHÖN sagen! Dieses cross-browser Problem hat mich tagelang geplagt – Ihre prägnante, saubere Methode war perfekt.