css mit Adi Prinz

Einen Würfel aus sechs Flächen erstellen

Aufbau eines CSS-3D-Würfels

Ein Würfel besteht aus einem gemeinsamen 3D-Container und sechs Flächen. Jede Fläche wird gedreht und anschließend entlang der z-Achse an ihre räumliche Position verschoben.

Fläche Drehung Verschiebung
Vorderseite rotateY(0) translateZ(75px)
Rückseite rotateY(180deg) translateZ(75px)
Rechte Seite rotateY(90deg) translateZ(75px)
Linke Seite rotateY(-90deg) translateZ(75px)
Oberseite rotateX(90deg) translateZ(75px)
Unterseite rotateX(-90deg) translateZ(75px)
Der Würfel ist 150px breit und hoch. Die Flächen werden deshalb um die halbe Kantenlänge – also 75px – vom Mittelpunkt entfernt.

HTML-Struktur des Würfels

Der äußere Bereich stellt die Perspektive bereit. Darin befindet sich der eigentliche Würfel mit seinen sechs Flächen.

<div class="cube-scene">
  <div class="cube">
    <div class="cube-face cube-front">
      vorne
    </div>

    <div class="cube-face cube-back">
      hinten
    </div>

    <div class="cube-face cube-right">
      rechts
    </div>

    <div class="cube-face cube-left">
      links
    </div>

    <div class="cube-face cube-top">
      oben
    </div>

    <div class="cube-face cube-bottom">
      unten
    </div>
  </div>
</div>
    
  1. .cube-scene enthält die Eigenschaft perspective.
  2. .cube erhält transform-style: preserve-3d.
  3. Die sechs Flächen liegen zunächst deckungsgleich übereinander.
  4. Jede Fläche wird durch eine eigene Transformation räumlich positioniert.

Vollständiger drehbarer Würfel

Der Würfel wird um die x- und y-Achse gedreht. Bewege den Mauszeiger über den Würfel, um die Animation anzuhalten.

vorne
hinten
rechts
links
oben
unten
.cube-scene {
  perspective: 700px;
}

.cube {
  position: relative;
  width: 150px;
  height: 150px;
  transform-style: preserve-3d;
}

.cube-front {
  transform:
    rotateY(0)
    translateZ(75px);
}

.cube-back {
  transform:
    rotateY(180deg)
    translateZ(75px);
}
    
Alle Flächen sind Kindelemente desselben 3D-Containers. Durch transform-style: preserve-3d bleiben ihre unterschiedlichen räumlichen Positionen erhalten.

Die sechs Flächen positionieren

Die Ausgangsfläche liegt in der x-y-Ebene. Für die Vorderseite genügt deshalb eine Verschiebung entlang der z-Achse.

Vorder- und Rückseite

.cube-front {
  transform:
    rotateY(0)
    translateZ(75px);
}

.cube-back {
  transform:
    rotateY(180deg)
    translateZ(75px);
}
        

Die Rückseite wird zuerst um 180deg gedreht. Ihre lokale z-Achse zeigt danach in die entgegengesetzte Richtung.

Rechte und linke Seite

.cube-right {
  transform:
    rotateY(90deg)
    translateZ(75px);
}

.cube-left {
  transform:
    rotateY(-90deg)
    translateZ(75px);
}
        

Beide Seiten werden um die y-Achse gedreht und danach entlang ihrer lokalen z-Achse nach außen verschoben.

Oberseite

.cube-top {
  transform:
    rotateX(90deg)
    translateZ(75px);
}
        

Durch die positive Drehung um die x-Achse wird die Fläche als Oberseite ausgerichtet.

Unterseite

.cube-bottom {
  transform:
    rotateX(-90deg)
    translateZ(75px);
}
        

Die negative Drehung um die x-Achse richtet die Fläche als Unterseite aus.

Warum zuerst gedreht und dann verschoben wird

CSS-Transformationsfunktionen werden als zusammengehörige Transformationsliste ausgewertet. Die Verschiebung bezieht sich dabei auf das durch die Drehung ausgerichtete Koordinatensystem der Fläche.

.cube-right {
  transform:
    rotateY(90deg)
    translateZ(75px);
}
    

Die Fläche wird seitlich ausgerichtet. Anschließend bewegt translateZ(75px) sie entlang ihrer nun seitlich zeigenden lokalen z-Achse an die rechte Würfelseite.

Werden Drehung und Verschiebung vertauscht, entsteht eine andere Position. Bei zusammengesetzten 3D-Objekten ist die Reihenfolge der Transformationsfunktionen deshalb besonders wichtig.

Die halbe Kantenlänge berechnen

Jede Fläche muss vom Mittelpunkt des Würfels bis zu seiner Außenseite verschoben werden. Dieser Abstand entspricht der halben Kantenlänge.

Kantenlänge: 150px
Abstand zum Mittelpunkt: 150px / 2 = 75px
    

Wird die Größe des Würfels geändert, muss auch der Wert für translateZ() angepasst werden.

Kantenlänge translateZ()
100px 50px
150px 75px
200px 100px
Sind Kantenlänge und Verschiebung nicht aufeinander abgestimmt, entstehen Lücken zwischen den Flächen oder die Flächen überschneiden sich.

Die Würfelgröße mit einer CSS-Variable steuern

Statt Größe und Verschiebung mehrfach einzutragen, kann eine benutzerdefinierte CSS-Eigenschaft verwendet werden.

.cube {
  --cube-size: 150px;

  width: var(--cube-size);
  height: var(--cube-size);
}

.cube-face {
  width: var(--cube-size);
  height: var(--cube-size);
}

.cube-front {
  transform:
    rotateY(0)
    translateZ(calc(var(--cube-size) / 2));
}
    
Wird --cube-size geändert, passen sich die Kantenlänge und der Abstand der Flächen automatisch an.

Den gesamten Würfel animieren

Die Animation wird auf den gemeinsamen Würfelcontainer gelegt. Die sechs Flächen behalten dabei ihre festen Positionen innerhalb des Würfels.

.cube-animation {
  animation: rotate-cube 10s linear infinite;
}

@keyframes rotate-cube {
  from {
    transform:
      rotateX(-20deg)
      rotateY(0);
  }

  to {
    transform:
      rotateX(340deg)
      rotateY(360deg);
  }
}
    

Während der Animation wird der Würfel einmal vollständig um die x- und y-Achse gedreht.

Die einzelnen Flächen benötigen keine eigene Animation. Sie bewegen sich gemeinsam mit ihrem Elternelement.

Transparente und undurchsichtige Flächen

Leicht transparente Hintergründe machen auch weiter hinten liegende Flächen sichtbar. Dadurch lässt sich der räumliche Aufbau des Würfels besonders gut erkennen.

Leicht transparent

.cube-face {
  background-color:
    rgba(13, 110, 253, 0.78);
}
        

Hintere Flächen scheinen teilweise durch die vorderen Flächen hindurch.

Undurchsichtig

.cube-face {
  background-color: #0d6efd;
}
        

Nur jene Flächen sind sichtbar, die aus der aktuellen Perspektive nicht verdeckt werden.

Wird opacity auf dem gesamten Würfelcontainer verwendet, kann das die 3D-Darstellung beeinflussen. Transparente Farben direkt auf den einzelnen Flächen sind für dieses Beispiel besser geeignet.

Rückseiten der Würfelflächen

Bei einem geschlossenen Würfel sind normalerweise die Außenseiten der Flächen sichtbar. Mit backface-visibility kann gesteuert werden, ob die Rückseiten zusätzlich dargestellt werden.

.cube-face {
  backface-visibility: hidden;
}
    
  • Mit hidden werden die nach innen gerichteten Rückseiten nicht dargestellt.
  • Mit visible können die Flächen auch von ihrer Rückseite sichtbar sein.
  • Für einen normalen geschlossenen Würfel ist backface-visibility: hidden meistens sinnvoll.

Animation und reduzierte Bewegung

Dauerhafte Drehbewegungen können für manche Benutzer unangenehm sein. Die Einstellung prefers-reduced-motion sollte deshalb berücksichtigt werden.

@media (prefers-reduced-motion: reduce) {
  .cube-animation {
    animation: none;
    transform:
      rotateX(-20deg)
      rotateY(35deg);
  }
}
    
Die Animation dient nur zur Veranschaulichung. Wichtige Inhalte dürfen nicht davon abhängig sein, dass der Benutzer den drehenden Würfel beobachten oder bedienen kann.

Eine drehbare 3D-Bildergalerie erstellen