Konische Verläufe in CSS

Avatar of Shankar Cabus
Shankar Cabus am

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

Wenn ich Filter, Schatten, Transformationen oder Gradient-Hintergründe in CSS erstelle, fühlt es sich großartig an. Wer hätte gedacht, dass CSS so weit kommen würde. Keine Notwendigkeit, Bilder für so etwas zu verwenden. Ich kann fast hören, wie der Browser mir sagt: „Mach dir keine Sorgen, ich mache das für dich.“

Trotz all dieser Entwicklung hat CSS immer noch Einschränkungen. Beispielsweise können Hintergrundverläufe nur in linearer oder radialer Form erstellt werden, aber nicht in einer konischen Form.

Im Jahr 2011 begann Lea Verou einen Thread zur Implementierung eines nativen CSS-konischen Verlaufs und erstellte eine Entwurfsspezifikation, die bereits in den offiziellen Entwurf des W3C aufgenommen wurde. Wir müssen jedoch immer noch darauf warten, dass das W3C die Funktion formalisiert und die Browser sie implementieren, was noch einige Zeit dauern könnte. In der Zwischenzeit zeige ich Ihnen, wie Sie einen konischen Verlauf mit nur CSS3 simulieren können.

Beispiel für einen konischen Verlauf.

Schön, nicht wahr? Schauen wir uns den Code an!

Der Anfang

Um Code-Duplizierung zu reduzieren, verwende ich Sass. Eines der interessantesten Features von CSS-Präprozessoren ist das @mixin. Ein @mixin ist eine Mischung aus Funktion und Include, die bei Aufruf ihren Inhalt zurückgibt.

@mixin circle($size) {
  content: "";
  position: absolute;
  border-radius: 50%;
  width: $size;
  height: $size;
  left: calc(50% - #{$size/2});
  top: calc(50% - #{$size/2});
}

Dieses @mixin wird nur verwendet, um Eigenschaften von Form und Platzierung festzulegen, und erstellt einen Kreis mit absoluter Position, der horizontal und vertikal relativ zu seinem Elternelement zentriert ist.

Die Magie!

Durch die Kombination eines @mixin circle mit der clip-Eigenschaft können wir einen Halbkreis erhalten. Beginnen wir mit der Erstellung eines vollen Kreises, indem wir zwei Halbkreise (mit unterschiedlichen Farben) zusammenlegen. Können Sie sich vorstellen, was passieren wird, wenn wir einen der Halbkreise drehen? Magie!

$wheel: 15em;
.color {
  @include circle($wheel);
  background: red;
  clip: rect(0, $wheel, $wheel, #{$wheel/2});
  &:after {
    @include circle($wheel);
    background: blue;
    clip: rect(0, #{$wheel/2}, $wheel, 0);
    transform: rotate(45deg);
  }
}

Die clip: rect (top, right, bottom, left)-Eigenschaft beschränkt den sichtbaren Bereich auf ein rechteckiges Element, wodurch im obigen Beispiel nur die Hälfte des roten Kreises sichtbar ist. Das gleiche Prinzip wird auf den blauen Kreis, das .color:after-Element, angewendet. Zu diesem Zeitpunkt hätten wir einen vollen Kreis, der halb rot und halb blau ist. **Die transform-Eigenschaft bewirkt jedoch, dass der sichtbare Bereich des blauen Kreises in den des roten Kreises eindringt**. Beispiel ansehen.

Halbkreise mit clip-Eigenschaft

Der bunte Regenschirm

Bunter Regenschirm

Wir wissen bereits, wie dieser Zaubertrick funktioniert. Erstellen wir einen Regenschirm mit 12 Farben

<div class="wheel">
  <ul class="umbrella">
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
    <li class="color"></li>
  </ul>
</div>

Da wir einen vollen Kreis durch die Kombination von Halbkreisen erstellen wollen, müssen wir ab dem siebten Element (dem ersten Element der zweiten Hälfte) den Clip umkehren

.color, .color:nth-child(n+7):after {
  clip: rect(0, $wheel, $wheel, #{$wheel/2});
}
.color:after, .color:nth-child(n+7) {
  @include circle($wheel);
  clip: rect(0, #{$wheel/2}, $wheel, 0);
}

Ab dem siebten Element wird das .color zu einem Halbkreis mit der linken Hälfte des Kreises, und die .color:after-Elemente gehen zur rechten Hälfte des Kreises über.

Wir sind fast fertig!! Wir müssen die Farben und den Winkel jedes Elements ändern. Wieder einmal missbrauchen wir die Macht von Sass, um 26193^42 Zeilen Code in etwas mehr als 10 zu generieren ;)

$colors: (#9ED110, #50B517, #179067, #476EAF, #9f49ac, #CC42A2, #FF3BA7, #FF5800, #FF8100, #FEAC00, #FFCC00, #EDE604);
@for $i from 0 to length($colors) {
  .color:nth-child(#{1+$i}):after {
    background-color: nth($colors, $i+1);
    @if $i < 6 {
      transform: rotate(#{30*(1+$i)}deg);
      z-index: #{length($colors)-$i};
    } @else {
      transform: rotate(#{-30+(30*(1+$i))}deg);
    }
  }
}

Zuerst definieren wir das $colors-Array mit den „12 Farben des Regenbogens“ und iterieren dann über die Liste, um den Selektor .color:nth-child(n):after mit den Eigenschaften background-color, rotate und z-index zu erstellen.

Die rotate-Eigenschaft hat einige wichtige Punkte. Ihr Winkel wird entsprechend der Anzahl der Farben im Kreis definiert. In unserem Fall gibt es 12 Farben, also ist 360/12 = 30 die Drehung jeder Farbe. Aber ab dem siebten Element beginnt die andere Hälfte des Kreises, erinnern Sie sich? Somit stoppt der gerade beschriebene Prozess am siebten Element. Wir beginnen dann denselben Prozess erneut, aber diesmal erfolgt die Drehung in eine andere Richtung. Deshalb gibt es ein @else mit rotate(#{-30+(30*($i+1))}deg), das 30 Grad von den Elementen der zweiten Hälfte des Kreises subtrahiert.

Wenn Sie ein guter Beobachter sind (und bisher alles verstanden haben), sollten Sie bemerkt haben, dass unser Regenschirm eigentlich ein Fächer ist! Bazinga! Damit die letzte Farbe der ersten Hälfte des Kreises nicht über andere Farben ragt, müssen wir den Index dieser Elemente umkehren. Zum Beispiel: z-index (6) = 1 und z-index (1) = 6.

Etwas mehr Magie

Schließlich müssen wir den Übergang zwischen den Farben erleichtern. Wir wollen ja keinen Regenbogen-im-Regenschirm-Stil, sondern einen konischen Verlauf!

.umbrella {
  -webkit-filter: blur(1.7em);
}

.wheel {
  overflow: hidden;
  box-shadow: inset 0 0 0 3em rgba(0, 0, 0, 0.3);
}

Der blur-Filter ist für das Mischen der Farben verantwortlich. Aber durch das Anwenden des Weichzeichners stoßen die Farben an die Grenzen des Kreises. Deshalb wurde auch die overflow: hidden-Eigenschaft zum .wheel-Element hinzugefügt. Der innere box-shadow wird verwendet, um die Ränder abzudunkeln, die „ausgewaschen“ wurden. Dies ist das Endergebnis

Siehe den Pen Conical gradient in pure CSS von Shankar Cabus (@shankarcabus) auf CodePen

Demo

Der konische Verlauf kann auf verschiedene Weise verwendet werden, um unterschiedliche Effekte zu erzielen. Eine der interessantesten Anwendungen ist jedoch die Farbwaage, wie im folgenden Beispiel

Siehe den Pen Color Picker in Pure CSS von Shankar Cabus (@shankarcabus) auf CodePen

Andere Demos

Hinweis des Herausgebers: Ich habe im Laufe der Zeit viele andere Ansätze dazu gesehen. Ich werde sie hier als Referenz einfügen.

Siehe den Pen css conical gradient von Kai Waddington (@waddington) auf CodePen.

Ein weiteres Demo von Michael Wehner.