Die Verwendung des CSS :target-Selektors

Avatar of Chris Coyier
Chris Coyier am

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

Der CSS :target-Pseudoselektor in CSS passt, wenn der Hash in der URL und die ID eines Elements gleich sind.

Der aktuelle Hash der URL ist "voters"
<section id="voters"> 
   Content
</section>
:target {
   background: yellow;
}

Solange diese URL so ist, erhält das section-Element einen gelben Hintergrund, wie in unserem CSS festgelegt.

Wann würden Sie das verwenden?

Eine Möglichkeit besteht darin, wenn Sie mit "Zuständen" stylen möchten. Wenn die Seite einen bestimmten Hash hat, befindet sie sich in diesem Zustand. Es ist nicht ganz so vielseitig wie die Manipulation von Klassennamen (da es nur eine geben kann und sie nur mit einem Element in Beziehung stehen kann), aber es ist ähnlich. Alles, was Sie tun könnten, um eine Klasse zu ändern, um den Zustand zu ändern, könnten Sie tun, wenn das Element im Zustand :target ist. Zum Beispiel: Farben ändern, Position ändern, Bilder ändern, Dinge ein-/ausblenden, was auch immer.

Ich würde diese Faustregeln verwenden, wann :target eine gute Wahl ist

  1. Wenn ein "Zustand" benötigt wird
  2. Wenn das Sprungverhalten akzeptabel ist
  3. Wenn es akzeptabel ist, die Browserhistorie zu beeinflussen

Wir werden all diese Dinge in diesem Artikel behandeln.

Wie bekommt man Hashes in URLs?

Der häufigste Weg ist, dass ein Benutzer auf einen Link klickt, der einen Hash enthält. Es kann ein interner (gleiche Seite) Link oder eine vollständige URL sein, die zufällig mit einem Hash und einem Wert endet. Beispiele

<a href="#voters">Go To There</a>

<a href="http://example.com/#specific-part">Go To There</a>

Sprungverhalten

Unabhängig davon, ob es sich um einen Link zur gleichen Seite handelt oder nicht, **scrollt der Browser die Seite, bis das Element am oberen Rand des Fensters angezeigt wird**. Oder so weit wie möglich, wenn er nicht so weit scrollen kann. Das ist sehr wichtig zu wissen, denn das bedeutet, dass die Ausnutzung dieses "Zustands"-Verhaltens etwas knifflig/begrenzt ist.

Zum Beispiel habe ich einmal eine Vielzahl von Techniken ausprobiert, um funktionale CSS-Tabs zu replizieren, aber letztendlich entschieden, dass die Verwendung des Checkbox-Hacks eine bessere Idee war, da dies die Probleme mit dem Seiten-Springen vermeidet. Ian Hansson von CSS Science hat auch einige Beispiele für Tabs. Sein drittes Beispiel verwendet :target, und absolut positionierte Elemente, die oberhalb der Oberseite der Seite versteckt sind, um das Seiten-Springen zu verhindern. Das ist clever, aber keine wirkliche Lösung, da die Seite nach oben springen würde, wenn die Tabs weiter unten auf der Seite wären. Die Anker sind tatsächlich fixiert positioniert, was bedeutet, dass sie mit der Seite scrollen und kein Top-Jumping-Verhalten aufweisen. Extra clever!

Ein perfekter Anwendungsfall: Hervorheben von Abschnitten

Hier ist ein Problem: Wenn ein Hash-Link Sie durch die Seite zum relevanten Abschnitt springen lässt, versucht er, diesen Abschnitt bündig am oberen Rand des Browserfensters zu platzieren.

Aber was, wenn nicht genug Platz vorhanden ist, um unter diesem Abschnitt zu scrollen? Dieser Abschnitt ist sichtbar, aber er liegt nicht bündig oben, was seltsam und verwirrend sein kann.

Das kann desorientierend sein.

Ich erfinde das nicht. Aus eigener Erfahrung kann ich sagen, dass Seiten-Sprunglinks, die mich nicht genau an die Stelle bringen, zu der ich verlinkt habe, mich durcheinanderbringen. Das passiert meiner Meinung nach zu oft bei FAQ-Seiten, wo die verlinkten Abschnitte oft nicht sehr hoch sind.

Lösen wir das also!

Eine historische Methode hieß die Yellow Fade Technique. Sie wurde von 37signals in Situationen eingesetzt, in denen neue Inhalte zur Seite hinzugefügt wurden, und man versuchte, die Aufmerksamkeit des Benutzers darauf zu lenken. Jonathan Snook übernahm diese Idee für CSS und kombinierte sie mit :target.

Anstatt eines gelben Verblassens zeigen wir durch leichte Verschiebung nach rechts und Aufblitzen eines roten Randes an, auf welchen Abschnitt der gerade angeklickte Link verwies. Um Ihnen das Denken abzunehmen, hier ist es

Die Struktur besteht aus einer Navigationsleiste, die mit IDs auf Abschnitte verlinkt

<nav>
  <a href="#one">1</a>
  <a href="#two">2</a>
  <a href="#three">3</a>
</nav>

<section>
  <div id="one"><h2>One</h2>Pellentesque habitant morbi ...</div>
  <div id="two"><h2>Two</h2>Pellentesque habitant morbi ...</div>
  <div id="three"><h2>Three</h2>Pellentesque habitant morbi ...</div>
</section>

Wenn die Abschnitte im Zustand :target sind, verschieben sie sich mithilfe des translateX-Transforms leicht nach rechts (verhindert unschöne Textumbrüche oder ähnliches, was wir mit Padding bekommen könnten) und ein roter Rand wird durch Keyframe-Animationen eingeblendet.

:target {
  animation: highlight 1s ease;  
  transform: translateX(20px);     
}
@keyframes highlight {
  0% { border-left-color: red; }
  100% { border-left-color: white; }
}
section > div {
  border-left: 40px solid white;
  padding: 10px;
  transition: all 0.5s ease;     
  padding-right: 50px;
  margin-left: -20px;    
}

Das war's im Grunde schon. Ich würde das unter progressive enhancement einordnen, wenn Sie sich Sorgen um die Browserunterstützung machen. Das heißt, es ist nur ein schöner Touch, nicht lebensnotwendig.

Demo ansehen

Das Springen bekämpfen!

Nehmen wir an, Ihnen gefällt die Idee, :target für Zustände zu verwenden, aber Sie mögen das Seiten-Sprungverhalten nicht. Sie *können* den Hash-Link in einer URL ändern, ohne dass die Seite springt.

Mit jQuery könnten Sie alle Hash-Links ansprechen, ihr Standardverhalten verhindern und pushState (oder replaceState, nehme ich an) verwenden, um die URL zu ändern (was die Seite nicht verschiebt).

$("a[href^=#]").on("click", function(e) {
  e.preventDefault();
  history.pushState({}, "", this.href);
});

Sie könnten auch replaceState austauschbar verwenden, was die URL ändern würde, ohne einen Eintrag in die Browserhistorie hinzuzufügen. Manchmal möchten Sie das vielleicht, manchmal nicht. Zumindest haben Sie hier eine Wahl, die Sie nicht haben, wenn Sie dem Standardverhalten beim Klicken auf einen Hash-Link folgen, der immer hinzufügt.

Aber es gibt schlechte Nachrichten

Wenn sich die URL zu einem neuen Hash ändert, würde man denken, dass sich das aktuelle Ziel ändert und neuer CSS wirksam wird. Das tut es nicht (getestet bei aktuellen WebKit- und Firefox-Versionen zum Zeitpunkt des Schreibens). Das ist ein Bug.

Theoretisch könnten Sie die aktuelle Scrollposition der Seite messen und speichern, den Link natürlich springen lassen und sie dann auf die ursprüngliche Position zurücksetzen. Aber das klingt so furchtbar, dass ich mir nicht einmal die Mühe gemacht habe, eine Testseite dafür zu erstellen.

Mehr