Tabber kommen ursprünglich aus der Desktop-Windows-Welt und sind für das Web adaptiert worden - vielleicht ist dass das Problem :).
Ich habe mich auf Bitten eines Lesers auf jeden Fall mal an so ein Tabber gewagt und eine Wechselseite ganz ohne Javascript gebaut - die Skizze funktioniert auch in mobilen Browsern!
Vorbemerkung
Ich verwende in der Skizze verschiedene Hacks und Tricks - ich gebe eine etwas ausführlichere Erklärung dafür, damit das 'Warum' besser verständlich wird. Ich versuche außerdem was neues und erkläre CSS/HTML im Zusammenhang und nicht hintereinander ... mal sehen, ob's damit besser verständlich wird.Wrapper
Roll on - das ganze Gadget kommt in ein Wrapper. Weil wir in der Skizzefloaten
, legen wir unten einen Div-Container mit clear: both
rein - sicher ist sicher :):
<div id="tabber"> <div style="clear: both"></div> </div>Weil wir mit
position: absolute
Eigenschaften arbeiten, müssen wir zwingend dem Element eine Mindesthöhe geben - sonst kollabiert die Sidebar:
#tabber { display: block; position: relative; min-height: 260px; }Wir verwenden in dieser Skizze außerdem für alle HTML Elemente die
border-sizing
Eigenschaft border-box
.
#tabber, .tab, .content_inner, label { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; }Dadurch ersparen wir uns später das nervige Umrechnen mit Padding, Margin und Border ...
Die Input-Elemente
In den Wrapper kommen nun dreiinput
Elemente mit dem dazugehörigen Label:<div id="tabber"> <div class="tab"> <input type="radio" id="tab-1" name="tab-group-1" checked="checked" > <label for="tab-1">About</label> </div> <div class="tab"> <input type="radio" id="tab-2" name="tab-group-1" > <label for="tab-2">Where?</label> </div> <div class="tab"> <input type="radio" id="tab-3" name="tab-group-1"> <label for="tab-3">What?</label> </div> <div style="clear: both"></div> </div>Die dazugehörigen Div-Container bekommen nun eine _feste_ Weite und Höhe - außerdem werden sie nach Rechts gefloatet:
.tab { float: left; position: relative; width: 160px; height: 40px; margin-left: -1px; left: 1px; text-align: center; margin: 0; padding: 0; }
margin-left: -1px
ist ein Hack, um in älteren Browser das Kollabieren der Tabs nach Rechts zu verhindern. Außerdem normalisieren wir die inneren und äußeren Abstände noch mal (ist wegen der Blogger-CSS notwendig).
Der Input-Hack
Jetzt kommt etwas sehr cleveres, wir nehmen nämlich zum 'klicken' nicht die Labels, sondern dasinput
Element - Grund ist, das input
Element lässt sich auch in mobilen Browsern klicken, Labels dagegen nicht..tab input { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 100; opacity: 0; cursor: pointer; }Das
input
Element nimmt damit die volle Fläche des Tabs ein, liegt wegen des Z-Index ganz oben und wird dann mit opacity
'Durchsichtig' gemacht, d.h. ihr seht es nicht mehr, könnt es aber nach voll benützen.Jetzt noch a bisserl Style:
.tab label { display: block; width: 100%; height: 100%; background: #eee; border: 1px solid #ccc; border-radius: 10px 10px 0 0; line-height: 40px; }
Der Innencontainer
Zuletzt legen wir unter jedem Label noch einen Div-Container, der den Inhalt des Tabbers trägt:<div id="tabber"> <div class="tab"> <input type="radio" id="tab-1" name="tab-group-1" checked="checked" > <label for="tab-1">About</label> <div class="content_inner"><span>All about Me!</span></div> </div> <div class="tab"> <input type="radio" id="tab-2" name="tab-group-1" > <label for="tab-2">Where?</label> <div class="content_inner"><span>Where do i come frome?</span></div> </div> <div class="tab"> <input type="radio" id="tab-3" name="tab-group-1"> <label for="tab-3">What?</label> <div class="content_inner"><span>Should i cry like a baby or die like a man?</span></div> </div> <div style="clear: both"></div> </div>Die Breite des Innencontainers ist 3x Breite/Tabs (3x160px = 480px)
.content_inner { width: 480px; height: 200px; position: absolute; left: 0; border: 1px solid #ccc; overflow: hidden; z-index: -1; }Die Elemente _innerhalb_ des Innencontainers werden ausgeblendet:
.content_inner > * { position: relative; opacity: 0; z-index: -1; }Der Universalselektor * ist ein Trick und erlaubt uns, jede Art von Inhalt in den Container zu legen ... Bilder, Links, Text whatever - alles wird ausgeblendet.
Zuletzt brauchen wir noch einen Korrekturwert, um die einzelnen Container exakt übereinander zu bekommen:
#tab-1 ~ .content_inner { left: 0 } #tab-2 ~ .content_inner { left: -160px } #tab-3 ~ .content_inner { left: -320px }Jeder Container wird dabei um eine Tab'breite' nach links verschoben - verständlich, oder?
Checkbox ist :checked
Kommen wir zum spannenden Teil - was passiert, wenn ein input
Element gedrückt wird, d.h. die Eigenschaft :checked
bekommt?
#tab-1:checked ~ .content_inner, #tab-2:checked ~ .content_inner, #tab-3:checked ~ .content_inner { background: #fff; z-index: 10; border-top: #fff; } input:checked ~ .content_inner > * { position: relative; opacity: 1; z-index: 10; } input:checked ~ label { background: #fff; border-bottom: #fff; }Wir verändern Hintergrund und Linien so, dass der Eindruck einer 'gemeinsamen' Fläche zwischen Tab und Innencontainer entsteht. Außerdem wird der Innenbereich sichtbar ...
Smooth
... aber auf ein ganz langweilige Art, der Innenbereich wird halt sichtbar. So what? Nicht besonders spannend, oder? Deswegen legen wir jetzt noch eine smoothe Bewegung drauf:#tab-1 ~ .content_inner > *, #tab-3 ~ .content_inner > * { position: relative; margin-left: -400px; text-align: center; line-height: 200px; -webkit-transition: margin-left 1.6s ease; -moz-transition: margin-left 0.6s ease; -ms-transition: margin-left 0.6s ease; -o-transition: margin-left 0.6s ease; } #tab-2 ~ .content_inner > * { position: relative; margin-left: 400px; text-align: center; line-height: 200px; -webkit-transition: margin-left 0.6s ease; -moz-transition: margin-left 0.6s ease; -ms-transition: margin-left 0.6s ease; -o-transition: margin-left 0.6s ease; } #tab-1:checked ~ .content_inner > *, #tab-2:checked ~ .content_inner > *, #tab-3:checked ~ .content_inner > * { margin-left: 0; -webkit-transition: margin-left 0.6s ease; -moz-transition: margin-left 0.6s ease; -ms-transition: margin-left 0.6s ease; -o-transition: margin-left 0.6s ease; }Im Grundzustand verschieben wir den Inhalt um 400px nach Rechts beziehungsweise Links ... wenn der Innenteil angezeigt wird, machen wir mit einer Transition die Verschiebung wieder rückgängig. Ziemlich simpel ... ursprünglich wollte ich den Tab mit einer Drehbewegung einblenden, aber das sparre ich mir für den nächsten Post auf ....
Ansonsten wär's das - mission accomplished!
Vom Code Erschlagen?
Ihr fragt euch gerade, ob's wirklich so ein gute Idee ist, ein Tabber mit CSS zu bauen ... yeah, lustigerweise hat heute ein Banknachbar über einen Tabber mit Javascript geschrieben ... vielleicht ist das ja was für euch?Der unbestritten-beste-jemals-mit-Javascript-gebauter-Tabber-für-Blogger ist übrigens der von Greenlava.
Trotzdem CSS?
Obwohl es diese tollen Scripts gibt, würde ich es an eurer Stelle trotzdem mit einer reinen CSS Lösung versuchen, weil Javascript ein paar fiese Nebeneffekte hat, etwa bei iPad & Co. ziemliche Sprünge zu verursachen.Javascript sollte immer nur dann verwendet werden, wenn es keine CSS Alternative gibt ... und inzwischen sind die Browser so weit, dass ihr das relativ unbefangen einsetzen könnt - die Skizze funktioniert in allen richtigen Browsern, auf allen mobilen Browsern und im IE ab 8+.