CSS3-Nur Registerbereich

Avatar of Chris Coyier
Chris Coyier am

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

Wenn Sie an „Tabs“ denken, kommt Ihnen vielleicht sofort JavaScript in den Sinn. Auf einen Klick auf einen Tab warten, alle Panels ausblenden, dasjenige anzeigen, das zum gerade angeklickten Tab gehört. Alle großen JavaScript-Bibliotheken behandeln Tabs auf irgendeine Weise. Aber es gibt eine Möglichkeit, dieselbe Idee mit „reinem CSS“ zu erreichen. Genau wie wir es mit dem CSS-Bildwechsler getan haben, nehmen wir dieses traditionell JavaScript-basierte Projekt nur mit CSS in Angriff.

Tabs: ein allgegenwärtiges Entwurfsmuster

:target Pseudoklassen-Selektor

Das wichtigste befähigende Konzept hier ist der CSS-Pseudoklassen-Selektor :target. :target wird in Verbindung mit ID-Selektoren verwendet. Der Selektor stimmt überein, wenn die aktuelle URL einen Hash-Tag dieser exakten ID enthält. Wenn die aktuelle URL also lautet

https://css-tricks.de/#big-bam-boom

Und es gab ein Element mit dieser ID auf der Seite

<h1 id="big-bam-boom">Kaplow!</h1>

Dann wird dieser Selektor übereinstimmen

#big-bam-boom:target { color: red; }

Wie gelangt man zu einer URL mit einem solchen Hash-Tag? Sie haben Links, die sie aktivieren

<a href="#big-bam-boom">Mission Control, we're a little parched up here.</a>

Browser-Unterstützung / CSS3

Normalerweise würde ich ein Tutorial wie dieses mit einem kleinen Abschnitt zur Browserunterstützung abschließen. Aber es ist in diesem Fall ziemlich wichtig, also legen wir es jetzt beiseite. :target gilt als CSS3. Es hat breite Unterstützung in allen wichtigen aktuellen Browsern. Natürlich bin ich ganz dafür, die Unterstützung für IE 6 einzustellen, also wen kümmert es, wenn es darin nicht funktioniert (tut es nicht), aber :target wird auch in IE 7 oder 8 nicht unterstützt. Diese Browser sind immer noch sehr relevant, was dieses gesamte Tutorial in eine unterhaltsame/lehrreiche Kategorie einordnet, anstatt in eine Kategorie für die Verwendung in der Live-Produktion.

Wenn Sie es natürlich in der Produktion verwenden möchten, wäre eine Option die Verwendung von bedingten Kommentaren, um JavaScript hinzuzufügen, damit sie funktionieren. Das werden wir hier nicht speziell behandeln.

Sauberes HTML

Beginnen wir gleich mit einer schönen und sauberen HTML-Struktur für unseren baldigen Registerbereich

<div class="tabbed-area">

	<ul class="tabs group">
	    <li><a href="#box-one">Tab 1</a></li>
	    <li><a href="#box-two">Tab 2</a></li>
	    <li><a href="#box-three">Tab 3</a></li>
	</ul>
	
	<div class="box-wrap">
	
		<div id="box-one">
		  <!-- box two content -->
		</div>
		
		<div id="box-two">
		  <!-- box two content -->
		</div>
		
		<div id="box-three">
		  <!-- box two content -->
		</div>
	
	</div>

</div>

Ich würde das als perfekt sauber bezeichnen. Selbst wenn CSS deaktiviert ist, sehen Sie eine Liste von Links, die jeweils zur entsprechenden Inhalts-Div auf der Seite springen.

CSS

Die Tabs selbst werden wir als horizontale Reihe von Links einrichten.

.tabs { list-style: none; }
.tabs li { display: inline; }
.tabs li a { color: black; float: left; display: block; padding: 4px 10px; margin-left: -1px; position: relative; left: 1px; background: white; text-decoration: none; }
.tabs li a:hover { background: #ccc; }

Wenn Sie alle Links so nebeneinander schieben, wird das übergeordnete Element kollabieren. Lassen Sie uns also die alte clearfix-Klasse hinzufügen, damit wir sie auf dem übergeordneten Element verwenden könnenuldamit es eine natürliche Höhe hat. Keine Notwendigkeit für IE 6- und 7-Hacks hier, da keiner von beiden diese Technik sowieso unterstützt.

.group:after { visibility: hidden; display: block; font-size: 0; content: " "; clear: both; height: 0; }

Lassen Sie uns nun die grundlegende Formatierung für die Panels einrichten. Es gibt eine umgebende Div für alle Panels. Der Zweck davon ist, einen relativen Positionskontext zu setzen, damit wir Panels darin absolut positionieren können. Alle Panels werden die gleiche Höhe und Breite haben und genau übereinander positioniert sein. Sowohl Panels als auch Tabs teilen sich denselben 1px-Rand.

.box-wrap { position: relative; min-height: 250px; }
.tabbed-area div div { background: white; padding: 20px; min-height: 250px; position: absolute; top: -1px; left: 0; width: 100%; }
.tabbed-area div div, .tabs li a { border: 1px solid #ccc; }

Der magische Teil, der es zum Laufen bringt, ist so einfach wie die Anpassung des z-Index der Panels, wenn sie „targetet“ werden.

#box-one:target, #box-two:target, #box-three:target {
  z-index: 1;
}

Ach du Schreck… Was ist mit der Hervorhebung des aktuellen Tabs?

Was wir bisher haben, ist ein voll funktionsfähiger Registerbereich. Sie klicken auf den Tab, der entsprechende Inhalt in diesem Tab wird geladen. Funktional, aber nicht die hilfreichste Benutzeroberfläche. Es gibt überhaupt keine Rückmeldung, welcher Tab gerade angezeigt wird, weder beim Laden der Seite noch wenn Sie zu einem anderen Tab wechseln.

Das ist eine ziemlich große Hürde. Ich finde einen Weg, es zu lösen, und wir werden das hier durchgehen, aber es ist schmutzig. Die Wurzel des Problems ist, dass wir nicht „nach oben“ im Elementbaum zurückselektieren können. Wenn wir also IDs für die Panels benötigen, können wir in CSS nur Nachfahren dieses Divs beeinflussen, wenn es sich im :target-Zustand befindet. Zum Beispiel

#box-four:target a[href="#box-four"] { color: red; }

Das wäre eine coole Möglichkeit, nur diesen bestimmten Link auszuwählen, wenn dieses Panel aktiv ist, aber bis jetzt können wir das nicht tun, weil dieser Link kein Nachfahre des Panels ist.

Der einzige Weg, den ich bisher gefunden habe, dies zu lösen, ist, die Navigation tatsächlich zu Nachfahren der Panels zu machen. Das ist eine Enttäuschung, denn das bedeutet, dass jedes Panel die Tabs wiederholen muss….

<div class="box-wrap">

	<div id="box-four">
        <!-- content for panel -->
      
        <ul class="tabs group">
            <li class="cur"><a href="#box-four">Tab 4</a></li>
            <li><a href="#box-five">Tab 5</a></li>
            <li><a href="#box-six">Tab 6</a></li>
        </ul>
	</div>
	
	<div id="box-five">
	    <!-- content for panel -->
	
        <ul class="tabs group">
            <li><a href="#box-four">Tab 4</a></li>
            <li class="cur"><a href="#box-five">Tab 5</a></li>
            <li><a href="#box-six">Tab 6</a></li>
        </ul>
	</div>
	
	<div id="box-six">
	    <!-- content for panel -->
	
        <ul class="tabs group">
            <li><a href="#box-four">Tab 4</a></li>
            <li><a href="#box-five">Tab 5</a></li>
            <li class="cur"><a href="#box-six">Tab 6</a></li>
        </ul>
	</div>

</div>

Sehr ideal, ich weiß. Aber jetzt, da die Listen innerhalb der Panels sind, können wir einfach eine „current“-Klasse auf dem Listenelement verwenden, das der richtige entsprechende Link ist, und das formatieren. Und wir werden sicherstellen, dass die Tab-Navigation des aktuellen Panels über den Panels positioniert ist und „oben“ liegt, wenn es das Panel ist.

.cur-nav-fix .tabs { position: absolute; bottom: 100%; left: -1px; }
.cur-nav-fix .tabs li a { 
   background: -webkit-linear-gradient(top, white, #eee); 
   background: -moz-linear-gradient(top, white, #eee); 
   background: -ms-linear-gradient(top, white, #eee); 
   background: -o-linear-gradient(top, white, #eee); 
}
#box-four { z-index: 1; }
#box-four:target .tabs, #box-five:target .tabs, #box-six:target .tabs { z-index: 3; }
.cur-nav-fix .tabs li.cur a { border-bottom: 1px solid white; background: white; }

Jetzt mit Hervorhebung des aktuellen Tabs!

Update

Der obige Code ist, wie erwähnt, definitiv keine gute Vorgehensweise. Ich habe mit dieser Idee noch viel mehr herumgespielt, und die unten verlinkte Demo enthält eine ganze Reihe verschiedener Ideen dafür, einschließlich einiger brauchbarer Lösungen.

Demo und Download

Verwenden Sie es nach Belieben, aber seien Sie sich des IE 7-Problems bewusst. Alle HTML- und CSS-Dateien sind auf einer Seite, also wenn Sie sie „herunterladen“ möchten, kopieren Sie einfach den Code in eine HTML-Datei und speichern Sie ihn.

Demo ansehen

Hash it out

Sie werden in der Demo bemerken, dass, wenn Sie einen Tab im linken Bereich anklicken und dann auf einen Tab im rechten Bereich klicken, der linke Bereich zu seinem ursprünglichen Zustand zurückkehrt, anstatt seine aktuelle Ansicht beizubehalten. Das liegt alles am :target und seiner Beziehung zum Hash in der URL. Dagegen gibt es wirklich keinen Weg, ohne JavaScript, also wenn das für Sie nicht in Frage kommt, sollten Sie wahrscheinlich gleich zu JavaScript greifen.

Außerdem springen Hash-Tag-Links beim Anklicken „nach unten auf der Seite“, also beachten Sie auch, dass Ihr Browserfenster nach unten springt, um diesen Tab zum obersten Element zu machen (wenn genügend Platz zum Scrollen auf der Seite vorhanden ist), wenn Sie auf einen Tab klicken. Auch dagegen kann ich nach meinem Wissen nichts ohne JavaScript tun.

Weitere Ressourcen