Heim >Web-Frontend >CSS-Tutorial >Verschiedene Möglichkeiten, CSS -Gradientenschatten zu erhalten
Ich stelle oft eine Frage: Kann ich Schatten mit Gradientenfarben anstelle von festen Farben erstellen? Es gibt keine besonderen Eigenschaften in CSS, um dies zu erreichen (glauben Sie mir, ich habe danach gesucht), und alle Blog -Beiträge, die Sie dazu finden, sind im Grunde einige ähnliche CSS -Tricks mit Gradienten. Wir werden als nächstes einige dieser Tipps abdecken.
Aber zuerst ... ist ein weiterer Artikel über Gradientenschatten? Wirklich?
Ja, dies ist ein weiterer Beitrag zu diesem Thema, aber es ist anders. Zusammen werden wir die Grenzen überschreiten und eine Lösung finden, die etwas abdeckt, das ich nirgendwo anders gesehen habe: Transparenz . Die meisten Tipps funktionieren, wenn Elemente nicht transparente Hintergründe haben, aber was ist, wenn wir transparente Hintergründe haben? Wir werden diese Situation hier besprechen!
Bevor wir anfangen, lassen Sie mich meinen Gradienten -Schattengenerator vorstellen. Sie müssen nur die Konfiguration anpassen und können den Code abrufen. Aber lesen Sie weiter, denn ich werde Ihnen helfen, die gesamte Logik hinter dem Generieren des Codes zu verstehen.
Beginnen wir mit Lösungen, die 80% der gemeinsamen Situationen funktionieren. Der typischste Fall ist, dass Sie ein Element mit einem Hintergrund verwenden und ihm einen Gradientenschatten hinzufügen müssen. Hier besteht keine Notwendigkeit, Transparenz zu berücksichtigen.
Die Lösung besteht darin, sich auf ein Pseudoelement zu verlassen, das den Gradienten definiert. Sie setzen es hinter das eigentliche Element und wenden einen Unschärfenfilter darauf an.
<code>.box { position: relative; } .box::before { content: ""; position: absolute; inset: -5px; /* 控制扩散 */ transform: translate(10px, 8px); /* 控制偏移量 */ z-index: -1; /* 将元素置于后面 */ background: /* 你的渐变色在这里 */; filter: blur(10px); /* 控制模糊 */ }</code>
Der Code sieht viel aus, weil er viel hat. Hier erfahren Sie, wie Sie Box-Shadow anstelle eines Gradienten verwenden, wenn wir feste Farben anstelle von Gradienten verwenden.
<code>box-shadow: 10px 8px 10px 5px orange;</code>
Dies sollte Ihnen eine gute Vorstellung davon geben, was der Wert im ersten Code -Stück tut. Wir haben X- und Y -Offsets, Fuzzy -Radius und Diffusionsabstand. Beachten Sie, dass wir einen negativen Diffusionsabstandswert aus der Einschubeigenschaft benötigen.
Dies ist eine Demo, die nebeneinander mit klassisch
Wenn Sie genau hinschauen, werden Sie feststellen, dass die beiden Schatten etwas unterschiedlich sind, insbesondere die verschwommenen Teile. Dies ist nicht überraschend, denn ich bin mir ziemlich sicher, dass sich der Algorithmus für Filterattribute von dem von Box-Shadow unterscheidet. Es ist keine große Sache, denn das Endergebnis ist sehr ähnlich.Diese Lösung ist gut, hat aber immer noch einige Nachteile im Zusammenhang mit der Z-Index: -1-Deklaration. Ja, dort passiert ein "Stack -Kontext"!
Ich habe eine Transformation in das Hauptelement angewendet, und dann liegt der Schatten nicht mehr unter dem Element. Dies ist kein Fehler, sondern ein logisches Ergebnis von Stapelkontexten. Mach dir keine Sorgen, ich werde keine langweiligen Erklärungen zum Stapeln von Kontexten geben (ich habe dies in Stack -Überlauf -Threads gemacht), aber ich werde dir immer noch zeigen, wie man es behebt.
Die erste Lösung, die ich empfehle, ist die Verwendung der 3D -Konvertierung:
<code>.box { position: relative; } .box::before { content: ""; position: absolute; inset: -5px; /* 控制扩散 */ transform: translate(10px, 8px); /* 控制偏移量 */ z-index: -1; /* 将元素置于后面 */ background: /* 你的渐变色在这里 */; filter: blur(10px); /* 控制模糊 */ }</code>
Wir verwenden nicht Z -Index: -1, sondern eine negative Übersetzung entlang der Z -Achse. Wir haben alles in translate3d () eingestellt. Vergessen Sie nicht, das Transformationsstil zu verwenden: Preserve-3D auf dem Hauptelement;
Soweit ich weiß, hat diese Lösung keine Nebenwirkungen ... aber vielleicht sehen Sie eine. Wenn ja, teilen Sie bitte den Kommentarbereich mit und versuchen Sie, eine Lösung zu finden!
Wenn Sie aus irgendeinem Grund keine 3D-Konvertierung verwenden können, besteht eine andere Lösung darin, sich auf zwei Pseudo-Elemente zu verlassen-:: vor und :: Nachher. Einer erstellt einen Gradientenschatten, der andere kopiert den Haupthintergrund (und andere Stile, die Sie möglicherweise benötigen). Auf diese Weise können wir die Stapelreihenfolge von zwei Pseudoelementen leicht steuern.
<code>box-shadow: 10px 8px 10px 5px orange;</code>
Es ist wichtig zu beachten, dass wir die dazu zwingen, einen Stapelkontext zu erstellen, indem wir Z-Index: 0 oder ein anderes Attribut deklarieren, das dasselbe tut. Vergessen Sie auch nicht, dass das Pseudo-Element die Füllkiste des Hauptelements als Referenz behandelt. Wenn das Hauptelement Grenzen hat, muss dies bei der Definition des Pseudo-Element-Stils berücksichtigt werden. Sie werden feststellen, dass ich Inset: -2px auf :: nach der Betrachtung von Grenzen benutze, die für Hauptelemente definiert sind.
Wie gesagt, diese Lösung kann in den meisten Fällen gut genug sein, solange Sie keine Transparenz unterstützen müssen, möchten Sie einen Gradientenschatten. Aber wir kamen, um die Grenzen herauszufordern und zu überschreiten. Auch wenn Sie nicht das brauchen, worüber Sie als nächstes sprechen möchten, achten Sie bitte weiter. Sie können neue CSS -Tipps lernen, die Sie an anderer Stelle verwenden können.transparente Lösung
Die Idee ist, einen Weg zu finden, um alles in einem Bereich des Elements (innerhalb eines grünen Randes) zu erregen oder zu verbergen, während der externe Inhalt beibehalten wird. Dafür werden wir Clip-Pfad verwenden. Aber Sie fragen sich vielleicht, wie Clip-Pfad in einem Element
beschnitten werden kann. In der Tat gibt es keine Möglichkeit, dies zu tun, aber wir können es mit einem bestimmten Polygonmuster simulieren:
schau! Wir bekommen einen Gradientenschatten, der Transparenz unterstützt. Wir haben dem vorherigen Code nur einen Clip-Pfad hinzugefügt. Hier ist ein Diagramm, um den Polygon -Teil zu veranschaulichen.
<code>.box { position: relative; transform-style: preserve-3d; } .box::before { content: ""; position: absolute; inset: -5px; transform: translate3d(10px, 8px, -1px); /* (X, Y, Z) */ background: /* .. */; filter: blur(10px); }</code>
Der blaue Bereich ist der Teil, der nach dem Auftragen des Clip-Pfads sichtbar ist. Ich benutze Blue nur, um das Konzept zu veranschaulichen, aber in Wirklichkeit sehen wir nur Schatten innerhalb des Bereichs. Wie Sie sehen können, definieren wir vier Punkte und ihre Werte sind sehr groß (b). Mein großer Wert ist 100Vmax, aber es kann jeder große Wert sein, den Sie wollen. Die Idee ist sicherzustellen, dass wir genug Schattenraum haben. Wir haben vier weitere Punkte, die die Eckpunkte des Pseudoelements sind.
Pfeile geben den Pfad an, der das Polygon definiert. Wir beginnen von (-b, -b) und bis wir erreichen (0,0). Insgesamt brauchen wir 10 Punkte. Nicht 8 Punkte, weil die beiden Punkte ((-b, -b) und (0,0)) zweimal im Pfad wiederholt werden.
Wir müssen auch das Letzte tun , nämlich den Diffusionsabstand und den Offset. Die obige Demonstration funktioniert einfach, weil dies ein spezieller Fall ist, sowohl der Offset- als auch der Diffusionsabstand sind gleich 0.
Lassen Sie uns die Diffusion definieren und sehen, was passiert. Denken Sie daran, wir verwenden dazu einen negativen Werteinschub:Das Pseudoelement ist jetzt größer als das Hauptelement, daher ist der Clip-Pfad-Clip mehr als wir brauchen. Denken Sie daran, wir müssen immer den Teil des Hauptelements
in (den Bereich innerhalb des grünen Randes im Beispiel) erregen. Wir müssen die Position der vier Punkte im Clip-Pfad einstellen.
<code>.box { position: relative; } .box::before { content: ""; position: absolute; inset: -5px; /* 控制扩散 */ transform: translate(10px, 8px); /* 控制偏移量 */ z-index: -1; /* 将元素置于后面 */ background: /* 你的渐变色在这里 */; filter: blur(10px); /* 控制模糊 */ }</code>Wir haben eine CSS -Variable für den Diffusionsabstand definiert und die Polygonpunkte aktualisiert. Ich habe nicht berührt, wo ich den großen Wert genutzt habe. Ich aktualisiere nur die Punkte, die den Winkel des Pseudoelements definieren. Ich erhöhe alle Nullwerte--s und reduziere 100% der Werte--s.
Der Offset ist die gleiche Logik. Wenn wir Pseudoelemente konvertieren, werden die Schatten falsch ausgerichtet und wir müssen das Polygon erneut korrigieren und die Punkte in die entgegengesetzte Richtung bewegen.
<code>box-shadow: 10px 8px 10px 5px orange;</code>Es gibt zwei weitere Variablen für Offsets: --x und - -y. Wir verwenden sie in Transformation und haben auch den Clip-Pfad-Wert aktualisiert. Wir berühren Polygonpunkte immer noch nicht mit großen Werten, aber wir verschenken alle anderen Punkte -wir reduzieren -x aus X -Koordinaten und -Y aus Y -Koordinaten.
Jetzt müssen wir nur einige Variablen aktualisieren, um den Gradientenschatten zu steuern. Wenn wir dies tun, verwandeln wir auch den Fuzzy -Radius in eine Variable:
Benötigen wir noch 3D -Conversion -Fähigkeiten?Es hängt alles von der Grenze ab. Vergessen Sie nicht, dass die Referenz für Pseudo-Elemente das Füllkasten ist. Wenn Sie also Grenzen auf das Hauptelement anwenden, haben Sie eine Überlappung. Sie können den 3D -Conversion -Trick beibehalten oder den Einschubwert aktualisieren, um Grenzen zu berücksichtigen.
Dies ist die Version, mit der die 3D -Konvertierung durch den aktualisierten Einschubwert in der vorherigen Demonstration ersetzt wurde:
Ich denke, dies ist ein angemessenerer Ansatz, da die Diffusionsabstand genauer sein wird, da er mit Border-Box anstelle von Padding-Box beginnt. Sie müssen jedoch den Einschubwert entsprechend dem Rand des Hauptelements anpassen. Manchmal ist der Rand des Elements unbekannt und Sie müssen die vorherige Lösung verwenden.
Verwenden der vorherigen nicht transparenten Lösung können Sie Kontextprobleme auf Stapelprobleme stoßen. Mit transparenten Lösungen können Sie auf Grenzproblemen stoßen. Jetzt haben Sie Optionen und Möglichkeiten, diese Probleme zu lösen. 3D -Conversion -Trick ist meine bevorzugte Lösung, da er alle Probleme behebt (Online -Generatoren werden es auch berücksichtigen)
abgerundete Ecken
Border-Radius definieren: Erbe ist eine gute Idee, auch wenn Sie keine abgerundeten Ecken haben. Dies berücksichtigt potenzielle, abgerundete Ecken, die Sie möglicherweise in Zukunft oder abgerundeten Ecken von anderer Stelle hinzufügen möchten.
Die Situation des Umgangs mit transparenten Lösungen ist unterschiedlich. Leider bedeutet dies, eine andere Lösung zu finden, da Clip-Pfad die Kurve nicht verarbeiten kann. Dies bedeutet, dass wir den Bereich innerhalb des Hauptelements nicht schneiden können.
Wir fügen das Maskenattribut zur Mischung hinzu.
Dieser Teil ist sehr langweilig und es fällt mir schwer, eine allgemeine Lösung zu finden, die nicht auf magische Zahlen beruht. Am Ende hatte ich eine sehr komplexe Lösung, die nur eine Pseudoelement verwendet, aber der Code ist ein Chaos und deckt nur einige spezifische Situationen ab. Ich denke nicht, dass es sich lohnt, diesen Weg zu erkunden.
Um den Code zu vereinfachen, habe ich beschlossen, ein zusätzliches Element einzufügen. Im Folgenden sind die Marke:
<code>.box { position: relative; } .box::before { content: ""; position: absolute; inset: -5px; /* 控制扩散 */ transform: translate(10px, 8px); /* 控制偏移量 */ z-index: -1; /* 将元素置于后面 */ background: /* 你的渐变色在这里 */; filter: blur(10px); /* 控制模糊 */ }</code>
Ich verwende benutzerdefinierte Element Der Code mag etwas seltsam aussehen, aber wir werden die Logik dahinter Schritt für Schritt erklären. Als nächstes verwenden wir die Pseudoelement von Wie Sie sehen, verwendet der Pseudoelement den gleichen Code wie alle früheren Beispiele. Der einzige Unterschied besteht darin, dass die 3D-Transformation am Bitte beachten Sie, dass der Bereich des Ich weiß, dass dies ein bisschen schwierig ist, aber im Gegensatz zu Clip-Path berücksichtigt das Maskenattribut den Bereich des Elements außerhalb , um den Inhalt anzuzeigen und zu verbergen. Deshalb musste ich zusätzliche Elemente einführen - um den "äußeren" Bereich zu simulieren. Beachten Sie auch, dass ich eine Kombination aus Grenzen und Einschüssen verwende, um den Bereich zu definieren. Auf diese Weise kann ich die Polsterung des zusätzlichen Elements genauso wie das Hauptelement halten, sodass für das Pseudoelement keine zusätzlichen Berechnungen erforderlich sind. Eine weitere nützliche Sache, die aus der Verwendung zusätzlicher Elemente erhält, ist, dass die Elemente festgelegt sind und sich nur die Pseudoelemente bewegt (mit Übersetzer). Auf diese Weise kann ich die Maske leicht definieren, die der letzte Schritt dieses Tricks ist.
lasst uns das Beachten Sie, wie der interne Radius dem Grenzradius des Hauptelements entspricht. Ich habe einen großen Grenze (150px) und einen Grenzradius definiert, der dem großen Grand Hauptelementradius entspricht. Äußerlich habe ich einen Radius von 150px R. Intern habe ich 150px R - 150px = R.
Wir müssen den inneren (blauen) Teil verbergen und sicherstellen, dass der Grenze (rot) noch sichtbar ist. Zu diesem Zweck habe ich zwei Maskenschichten definiert-eine, die nur den Bereich des Inhaltsboxs und den anderen abdeckt, der den Grenzkastenbereich abdeckt (Standard). Ich schließe dann einen aus dem anderen aus, um die Grenze zu zeigen. Ich verwende dieselbe Technik, um Grenzen zu erstellen, die Gradienten und Grenzradius unterstützen. Ana Tudor hat auch einen guten Artikel über Maskenverbinden, und ich lade Sie ein, ihn zu lesen. Gibt es Nachteile dieser Methode? Ja, das ist definitiv nicht perfekt. Das erste Problem, auf das Sie begegnen können, bezieht sich auf die Verwendung von Grenzen für das Hauptelement. Wenn Sie es nicht berücksichtigen, kann dies zu einer leichten Fehlausrichtung des Radius führen. Dieses Problem besteht in unserem Beispiel, aber es fällt Ihnen möglicherweise schwer, es zu bemerken. relativ einfach festgelegt: Fügen Sie dem Einschub des Ein weiterer Nachteil ist der große Wert, den wir für Grenzen verwenden (150px im Beispiel). Dieser Wert sollte groß genug sein, um Schatten zu enthalten, aber nicht zu groß, um Überlauf- und Bildlaufprobleme zu vermeiden. Glücklicherweise berechnet der Online -Generator alle Parameter, um den optimalen Wert zu berechnen. Der letzte Nachteil ist mir klar, wenn Sie komplexe Grenzradius verwenden. Wenn Sie beispielsweise einen anderen Radius auf jede Ecke anwenden möchten, müssen Sie für jede Seite eine Variable definieren. Ich denke, dies ist kein echter Nachteil, aber es kann Ihren Code ein wenig schwieriger machen. Der Einfachheit halber berücksichtigt der Online -Generator nur einen einheitlichen Radius, aber Sie wissen jetzt, wie Sie den Code ändern, wenn Sie komplexe Radius -Konfigurationen berücksichtigen möchten. Wir haben das Ende erreicht! Die Magie hinter dem Gradientenschatten ist kein Geheimnis mehr. Ich versuche, alle Möglichkeiten und Probleme zu decken, die Sie möglicherweise haben. Wenn ich etwas verpasst habe oder dass Sie Probleme gefunden haben, können Sie es im Kommentarbereich melden, und ich werde es überprüfen. In Anbetracht der Tatsache, dass die De -facto -Lösung die meisten Ihrer Anwendungsfälle abdeckt, können viele davon überflüssig sein. Es ist jedoch gut, das „Warum“ und „Wie“ hinter der Technik zu verstehen und seine Grenzen zu überwinden. Außerdem haben wir eine großartige Übung beim Spielen von CSS -Bearbeitung und Matte bekommen. Natürlich können Sie den Online -Generator jederzeit verwenden, um Probleme zu vermeiden. <code>box-shadow: 10px 8px 10px 5px orange;</code>
<code>.box {
position: relative;
transform-style: preserve-3d;
}
.box::before {
content: "";
position: absolute;
inset: -5px;
transform: translate3d(10px, 8px, -1px); /* (X, Y, Z) */
background: /* .. */;
filter: blur(10px);
}</code>
<code>.box {
position: relative;
z-index: 0; /* 我们强制创建一个堆叠上下文 */
}
/* 创建阴影 */
.box::before {
content: "";
position: absolute;
z-index: -2;
inset: -5px;
transform: translate(10px, 8px);
background: /* .. */;
filter: blur(10px);
}
/* 复制主元素样式 */
.box::after {
content: "";
position: absolute;
z-index: -1;
inset: 0;
/* 继承在主元素上定义的所有装饰 */
background: inherit;
border: inherit;
box-shadow: inherit;
}</code>
<code>clip-path: polygon(-100vmax -100vmax,100vmax -100vmax,100vmax 100vmax,-100vmax 100vmax,-100vmax -100vmax,0 0,0 100%,100% 100%,100% 0,0 0)</code>
<code>.box {
position: relative;
}
.box::before {
content: "";
position: absolute;
inset: -5px; /* 控制扩散 */
transform: translate(10px, 8px); /* 控制偏移量 */
z-index: -1; /* 将元素置于后面 */
background: /* 你的渐变色在这里 */;
filter: blur(10px); /* 控制模糊 */
}</code>
<code>box-shadow: 10px 8px 10px 5px orange;</code>
<code>.box {
position: relative;
transform-style: preserve-3d;
}
.box::before {
content: "";
position: absolute;
inset: -5px;
transform: translate3d(10px, 8px, -1px); /* (X, Y, Z) */
background: /* .. */;
filter: blur(10px);
}</code>
Zusammenfassung
Das obige ist der detaillierte Inhalt vonVerschiedene Möglichkeiten, CSS -Gradientenschatten zu erhalten. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!