Rekursives CSS

Text von Frank Hellenkamp

Cascading Stylesheets und Rekursion

In der wenigen übrig bleibenden Zeit, teste ich gerne kurz verschiedene Ideen und Konzepte aus, über die ich während des Arbeitens stolpere. Eines davon ist, Stylesheets für Elemente rekursiv anzuwenden bzw. grafische Strukturen, die sich in Programmiersprachen mit rekursiven Strukturen ergeben, mit Hilfe von CSS zu simulieren. 

 

Das geht in dieser Form, da alle mit CSS (Cascading!) formatierten Elemente Eigenschaften ihrer Elternelemente erben und weil relativ und absolut positionierte Elemente ihren Fixpunkt an dem jeweiligen relativ oder absolut positionierten Elternelement festmachen. 

(Es ist auch eine Live-Vorschau der Beispiele verfügbar: http://sandbox.depage.net/css-recursion/ — man braucht aber einen modernen Browser, um einige Beispiele korrekt dargestellt zu bekommen.) 

Das grundlegende Markup

Das grundlegende Markup ist sehr simple. Wir haben einen Viewport und darin einfach geschachtelte Divs. Der Grund warum wir Divs dafür verwenden, ist einfach: Divs haben keine anderen Eigenschaften in HTML, außer dass sie Blockelemente sind. 

 

In diesem Beispiel haben wir eine Rekursionstiefe von 5 (Die nachfolgenden Beispielbilder habe alle eine Tiefe von 18): 

<div class="viewport test">
    <!-- {{{ children with recursion depth of 5 -->
    <div>
        <div>
            <div>
                <div>
                    <div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <!-- }}} -->
</div>

Und hier das Basis-Stylesheet für den Viewport: 

Alles, was sich nicht innerhalb seiner Fläche befindet wird ausgeblendet (overflow: hidden). 

.viewport {
    position: relative;
    background-color: #ffffff;
    width: 61em;
    height: 61em;
    margin: 1em;
    overflow: hidden;
}

Die zweite Instruktion (.viewport div div) ist wichtig: 

Jedes div innerhalb eines anderen div-Elements bekommt eine zunehmende Transparenz. Auf diese Weise bekommen wir ein Gefühl für Unendlichkeit (bzw. Rekursion ohne Abbruchbedingung) und wir sehen Elemente, die übereinander liegen. 

.viewport div div {
    opacity: 0.9;
}

Das erste einfache Beispiel: »Drittellung«

Im ersten einfachen Beispiel ist jede Box um ein Drittel kleiner als die übergeordnete Box (width: 66.66666%). 

.third div {
    position: relative;
    top: 0;
    left: 0;
    border-right-width: 1px;
    border-right-style: solid;
    border-color: #000000;
    width: 66.6666%;
    height: 100%;
}
.third div:hover {
    border-color: #ff0000;
}

Zur besseren Verdeutlichung: »Treppchen«

In dieser Treppe habe ich Nummern hinzugefügen, die zeigen welche Tiefe die jeweilige Box besitzt. Jede Box ist dabei 5em x 5em groß und gleichzeitig um 5em nach unten und 5em nach rechts verschoben: 

.staircase div {
    position: relative;
    top: 5em;
    left: 5em;
    border-width: 1px;
    border-style: solid;
    border-color: #000000;
    width: 5em;
    height: 5em;	
}
.staircase div:hover {
    border-color: #ff0000;
}

Drehen, drehen, drehen: »Rotation«

.rotation div {
    position: relative;
    top: 50%;
    left: 45%;
    border-width: 1px;
    border-style: solid;
    border-color: #000000;
    background: #dddddd;
    width: 5em;
    height: 5em;
    -webkit-transform: rotate(-50deg); 
    -moz-transform: rotate(-50deg);	
    -o-transform: rotate(-50deg);	
    transform: rotate(-50deg);	
}
.rotation div div {
    top: 5em;
    left: 5em;
}
.rotation div:hover {
    border-color: #ff0000;
}

Effekte: »Rotation 2«

.rotation2 div {
    position: relative;
    top: 50%;
    left: -10%;
    border-width: 1px;
    border-style: solid;
    border-color: #000000;
    background: #dddddd;
    width: 72em;
    height: 12em;
    -webkit-transform: rotate(-50deg); 
    -moz-transform: rotate(-50deg);	
    -o-transform: rotate(-50deg);	
    transform: rotate(-50deg);	
    -webkit-border-radius: 6em;
    -moz-border-radius: 6em;
    -o-border-radius: 6em;
    border-radius: 6em;
}
.rotation2 div div {
    top: 5em;
    left: 5em;
}
.rotation2 div:hover {
    border-color: #ff0000;
}

Das letzte Beispiel: »Rotation 3«

.rotation3 div {
    position: relative;
    top: 50%;
    left: -10%;
    border-width: 1px;
    border-style: solid;
    border-color: #000000;
    background: #dddddd;
    width: 72em;
    height: 2em;
    -webkit-transform: rotate(-50deg); 
    -moz-transform: rotate(-50deg);	
    -o-transform: rotate(-50deg);	
    transform: rotate(-50deg);	
    -webkit-border-radius: 6em;
    -moz-border-radius: 6em;
    -o-border-radius: 6em;
    border-radius: 6em;
}
.rotation3 div div {
    top: 5em;
    left: 5em;
}
.rotation3 div:hover {
    border-color: #ff0000;
}

Fazit

Zu diesem Zeitpunkt eigentlich nutzlos ;-) — aber man kann sehen, wie flexibel CSS ist und was für eine Reihe von Effekten man mit recht wenigen Styling-Angaben erzeugen kann. 

 

Wenn man das ganze dann noch mit anderen CSS Transformationen und CSS Transitions kombiniert, könnte das ganze noch sehr viel interessanter werden. 

Das behalten wir uns aber für einen späteren Zeitpunkt vor...