In diesem Beitrag werden wir CSS-Superkräfte einsetzen, um einen visuellen Effekt zu erzielen, bei dem sich zwei Elemente überlappen und miteinander verweben. Die Erleuchtung für dieses Design kam während eines kurzen Anflugs spiritueller Neugier, der mich auf die Website von The Bible Project führte. Sie erstellen wirklich coole Animationen, und ich meine, *wirklich* coole Animationen.
Meine Aufmerksamkeit wandte sich jedoch vom Spiritualismus ab und dem Webdesign zu, als ich immer wieder diese Ein-und-Aus-Randillustrationen bemerkte.

Ich fragte mich, ob so etwas mit reinem CSS gemacht werden könnte... und Halleluja, es ist möglich!
Siehe den Stift
Über und unter Randdesign mit CSS von Preethi Sam (@rpsthecoder)
auf CodePen.
Die wichtigsten CSS-Standards, die wir bei dieser Technik verwenden, sind CSS-Blend-Modi und CSS Grid.
Zuerst beginnen wir mit einem Bild und einem gedrehten Rahmen davor.
<div class="design">
<img src="bird-photo.jpg">
<div class="rotated-border"></div>
</div>
.design {
position: relative;
height: 300px;
width: 300px;
}
.design > * {
position: absolute;
height: 100%;
width: 100%;
}
.rotated-border {
box-sizing: border-box;
border: 15px #eb311f solid;
transform: rotate(45deg);
box-shadow: 0 0 10px #eb311f, inset 0 0 20px #eb311f;
}
Der rote Rahmen wird mit border erstellt. Seine box-sizing-Eigenschaft ist so eingestellt, dass die Rahmenbreite in den Abmessungen der Box enthalten ist, sodass der Rahmen nach dem Drehen zentriert um das Bild liegt. Andernfalls wäre der Rahmen größer als das Bild und würde in die untere rechte Ecke gezogen.

Dann wählen wir ein Paar gegenüberliegende Ecken des Bildes aus und überlagern ihre Quadranten mit ihrem entsprechenden Teil einer Kopie desselben Bildes wie zuvor. Dies verbirgt den roten Rahmen in diesen Ecken.
Wir müssen im Grunde einen Ausschnitt des Bildes erstellen, der wie unten aussieht, um ihn über den roten Rahmen zu legen.

.rotated-border-Element liegen.Wie ändern wir also das Bild, sodass nur zwei Quadranten sichtbar sind? CSS-Blend-Modi! Der Wert multiply ist das, was wir in diesem Fall anstreben. Dies verleiht einem Element Transparenz, indem Weiß aus dem Bild entfernt wird, um das dahinterliegende Element freizulegen.
Chris hat eine schöne Demo, die zeigt, wie ein roter Hintergrund mit dem Multiplizier-Blend-Modus durch ein Bild scheint.
Siehe den Stift
Hintergrund-Blending von Chris Coyier (@chriscoyier)
auf CodePen.
OK, nett, aber was ist mit diesen Quadranten? Wir bedecken die Quadranten, die wir verstecken wollen, mit weißen Gitterzellen, die das Bild in diesen spezifischen Bereichen vollständig durchscheinen lassen, mit einer Kopie des Vogelbilds direkt darüber im Quellcode.
<div id="design">
<img src="bird-photo.jpg">
<div class="rotated-border"></div>
<div class="blend">
<!-- Copy of the same image -->
<img src="bird-photo.jpg">
<div class="grid">
<!-- Quadrant 1: Top Left -->
<div></div>
<!-- Quadrant 2: Top Right -->
<div data-white></div>
<!-- Quadrant 3: Bottom Left -->
<div data-white></div>
<!-- Quadrant 4: Bottom Right -->
<div></div>
</div>
</div>
</div>
.blend > * {
position: absolute;
height: 100%;
width: 100%;
}
/* Establishes our grid */
.grid {
display: grid;
grid: repeat(2, 1fr) / repeat(2, 1fr);
}
/* Adds white to quadrants with this attribute */
[data-white]{
background-color: white;
}
Das Ergebnis ist ein Zwei-mal-Zwei-Gitter, dessen obere rechte und untere linke Quadranten weiß gefüllt sind, während sie zusammen mit dem Bild innerhalb von .blend gruppiert sind.
Für diejenigen unter Ihnen, die neu bei CSS Grid sind: Wir fügen ein neues .grid-Element hinzu, das zu einem "Grid"-Element wird, wenn wir display: grid; deklarieren. Dann verwenden wir die grid-Eigenschaft (die eine Kurzschreibweise ist, die kombiniert grid-template-columns und grid-template-rows), um zwei gleichmäßig verteilte Zeilen und Spalten zu erstellen. Wir sagen im Grunde: "Hey, Grid, wiederhole zwei gleiche Spalten und wiederhole zwei gleiche Zeilen in dir, um vier Felder zu bilden."

Jetzt wenden wir den Multiplizier-Blend-Modus auf .blend mit der Eigenschaft mix-blend-mode an.
.blend { mix-blend-mode: multiply; }
Das Ergebnis

Wie Sie sehen können, wirkt sich der Blend-Modus auf alle vier Quadranten aus und nicht nur auf die beiden, durch die wir sehen wollen. Das bedeutet, dass wir durch alle vier Quadranten sehen können, was den gesamten roten, gedrehten Kasten freilegt.
Wir wollen das Weiß zurückbringen, das wir in den oberen linken und unteren rechten Quadranten verloren haben, damit sie den roten, gedrehten Kasten dahinter verdecken. Fügen wir ein *zweites* Gitter hinzu, diesmal über .blend im Quellcode.
<div id="design">
<img src="bird-photo.jpg">
<div class="rotated-border"></div>
<!-- A second grid -->
<!-- This time, we're adding white to the image quandrants where we want to hide the red frame -->
<div class="grid">
<!-- Quadrant 1: Top Left -->
<div data-white></div>
<!-- Quadrant 2: Top Right -->
<div></div>
<!-- Quadrant 3: Bottom Left -->
<div></div>
<!-- Quadrant 4: Bottom Right -->
<div data-white></div>
</div>
<div class="blend">
<img src="bird-photo.jpg">
<div class="grid">
<!-- Quadrant 1: Top Left -->
<div></div>
<!-- Quadrant 2: Top Right -->
<div data-white></div>
<!-- Quadrant 3: Bottom Left -->
<div data-white></div>
<!-- Quadrant 4: Bottom Right -->
<div></div>
</div>
</div>
</div>
Das Ergebnis!

Zusammenfassend lässt sich sagen, dass der Browser die Elemente in unserer Demo wie folgt rendert:
- Ganz unten ist das Vogelbild (dargestellt durch die linke graue Form im Diagramm unten)
- Dann ein gedrehter roter Rahmen
- Darüber liegt ein Gitter mit weißen Zellen oben links und unten rechts (Ecken, in denen wir den roten Rahmen im Endergebnis nicht sehen wollen)
- Gefolgt von einer Kopie des vorherigen Vogelbilds und einem Gitter mit weißen Zellen oben rechts und unten links (Ecken, in denen wir den roten Rahmen sehen wollen) – beide zusammen gruppiert und mit dem Blend-Modus Multiplizieren versehen.

Vielleicht haben Sie einige Fragen zu dem Ansatz, den ich in diesem Beitrag verwendet habe. Lassen Sie mich versuchen, diese zu beantworten.
Was ist mit der Verwendung von CSS-Maskierung anstelle von CSS-Blend-Modi?
Für diejenigen unter Ihnen, die mit CSS-Maskierung vertraut sind – sei es mit mask-image oder clip-path – kann dies eine Alternative zur Verwendung von Blend-Modi sein.
Ich bevorzuge Blending, da es eine bessere Browserunterstützung als Masken und Clipping hat. Zum Beispiel unterstützen WebKit-Browser keine SVG-<mask>-Referenzen in der CSS-mask-image-Eigenschaft, und sie bieten auch nur teilweise Unterstützung für clip-path-Werte, insbesondere Safari.
Ein weiterer Grund für die Wahl des Blend-Modus ist die Bequemlichkeit, das Grid verwenden zu können, um eine einfache weiße Struktur zu erstellen, anstatt Bilder erstellen zu müssen (egal ob SVG oder anders).
Andererseits bin ich voll und ganz auf dem CSS-Blend-Modus-Zug, nachdem ich ihn für Aussparungstext, Textfragmentierungseffekt... und jetzt dies verwendet habe. Ich bin ziemlich voll dabei.
Warum haben Sie Grid für die Quadranten verwendet?
Die im Demo benötigten weißen Felder können natürlich auch anders erstellt werden, aber mit Grid ist es für mich einfacher. Wir hätten zum Beispiel auch Flexbox nutzen können. Verwenden Sie, was für Sie funktioniert.
Warum ein Datenattribut auf den Grid-Quadranten-Elementen verwenden, um sie weiß zu machen?
Ich habe es beim Codieren der Demo verwendet, ohne viel darüber nachzudenken – ich schätze, es war schneller zu tippen. Später habe ich daran gedacht, es in eine Klasse zu ändern, aber es so belassen, wie es war, weil das HTML so übersichtlicher aussah... zumindest für mich. :)
Ist "multiply" der einzige Blend-Modus, der für dieses Beispiel funktioniert?
Nein. Wenn Sie bereits etwas über Blend-Modi wissen, wissen Sie wahrscheinlich auch, dass Sie entweder screen, darken oder lighten verwenden können, um einen ähnlichen Effekt zu erzielen. (Sowohl screen als auch lighten benötigen schwarze Gitterzellen anstelle von weißen.)
Was für ein interessantes Design! Hier ist ein weiterer Ansatz: https://codepen.io/SirMorland/pen/KKKzoEm. Ich habe nur ein Bild verwendet, hatte aber separate Ränder für oben und unten. Es funktioniert möglicherweise nicht in allen Anwendungsfällen, aber ich denke, es ist vielleicht etwas effizienter, da es nicht mit Blend-Modi spielt.
Mein erster Gedanke, als ich das Bild in der Kopfzeile sah.
Das ist eine hervorragende Lösung, tolle Arbeit
In einfachen Fällen kann man einen
divverwenden, aber es ist schwieriger, die ganze Komponente perz-indexzu positionierenMeine bevorzugte Lösung. Vielen Dank!
Ich habe es nur ein wenig angepasst, um das img-Tag zurückzubekommen und nur eine Möglichkeit zu haben, über die Winkeldrehung nachzudenken. Scheint mir einfacher. ^^
Außerdem scheint z-index browserübergreifend überflüssig zu sein... Sieht jemand ein Problem, wenn z-index nicht verwendet wird?
Schöner Effekt und schöner Artikel! :)
Sie machen die Dinge hier vielleicht zu kompliziert – zumindest für diesen spezifischen Effekt, denke ich.
Obwohl Ihre Methode andere (komplexere) Dinge lösen könnte, könnten Sie einfach einige Pseudo-Elemente verwenden: https://codepen.io/dannievinther/pen/jOOqKmJ
Die Markup- und CSS-Struktur ist sauberer, glaube ich :)
Vielen Dank für Ihren Beitrag – er war sehr aufschlussreich
Ich stimme zu, dass dies viel sauberer ist, aber wenn Sie Schatten hinzufügen, wie im Beispiel hier, funktionieren Pseudo-Elemente nicht.
Das ist wirklich clever. Danke fürs Teilen.. :)
Toller Artikel! MS Edge hat einige Probleme mit der Verwendung von Attributselektoren. Die Probleme wurden im August 2017 gemeldet, aber bis heute bestehen die Probleme fort.
In diesem Beispiel werden Sie wahrscheinlich keine Probleme sehen. Ich habe Probleme bemerkt, wenn Elemente in JS mit einem Datenattribut angesprochen werden.
https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/13348719/
Das war eine sehr aufschlussreiche Anleitung! Ich werde dieses Rezept auf jeden Fall für zukünftige Projekte speichern.
Ich habe selbst ein wenig damit in CodePen herumgespielt und festgestellt, dass der Rahmen bis zu +/-64 Grad gedreht werden kann, ohne Probleme. Wenn man ihn jedoch auf 65 Grad oder höher dreht, schneidet der Rahmen mit den sekundären Gitterquadranten mit dem Daten-White-Attribut, sodass offensichtlich wird, dass sie alles überlagern.
Warum nicht einfach in Photoshop machen?
Das Gleiche kann man über alles sagen. Dagegen oder das Auscodieren ist nichts einzuwenden, obwohl Code effizienter sein kann. Außerdem ist es ziemlich cool und macht Spaß, es tun zu können.
Großartig, aber ich verstehe es immer noch nicht. Kann ich bitte die Grundlagen und Videos bekommen, die ich herunterladen kann? Ich lerne gerade HTML
So cool
Ich liebe deine Seite total! Das war alles für den Moment
Schöner Artikel! Ich habe deinen Stift in einer viel "einfacheren" (aber anderen) Version gegabelt: https://codepen.io/guizmath/pen/mddRLvg
Wirklich cooler Effekt. Ich kämpfe damit, den Blend-Modus zu verstehen, aber das ist gut :)
Mein Gehirn dachte an Pseudo-Elemente mit etwas z-index-Trickerei: https://codepen.io/mrwweb/pen/dyyvMRL?editors=1100
Ich wollte wirklich sehen, ob ich die element()-Funktion verwenden könnte, aber aus irgendeinem Grund konnte ich sie nicht zum Laufen bringen (in Firefox mit Präfix). Etwas, zu dem ich an einem anderen Tag zurückkommen werde.
Danke, dass Sie mir eine nette CSS-Eigenschaft erzählt haben, die ich noch nicht kannte, aber... Warum machen wir die Dinge so kompliziert? Ich würde diesen Effekt persönlich mit nur absoluter Positionierung für Quadranten und der background-position-Eigenschaft + z-index erzielen.
Ich habe ein neues Beispiel erstellt, bei dem das Bild-Element und die relativen semantischen und zugänglichen Eigenschaften beibehalten werden, unter Verwendung von benutzerdefinierten Eigenschaften und Pseudo-Elementen.