Ich habe Jake's "Cross-fading any two DOM elements is currently impossible" gelesen, was eine wunderbar nerdige Tiefenanalyse darüber ist, wie es keine wirkliche Möglichkeit gibt, Elemente buchstäblich überzublenden. Ja, man kann die Opazität beider Elemente animieren, aber selbst das ist nicht ganz dasselbe. Es stellt sich heraus, dass es in Chrome/WebKit eine CSS-Funktion namens -webkit-cross-fade() gibt, die den Trick macht. MDN sagt, sie sei spezifiziert, aber die implementierte Version unterscheidet sich, also ist es ein ziemliches Durcheinander… aber sie existiert
.el {
background: -webkit-cross-fade(url(img1.svg), url(img2.svg), 50%);
}
Ich wusste gar nicht, dass es so etwas gibt.
Das Erste, woran ich dachte, war: Wenn eines der Bilder nur ein leeres transparentes Bild wäre, würde das nicht dem anderen eine partielle Transparenz verleihen? Und somit wäre es eine Art Stellvertreter für background-opacity (was nicht existiert, aber sich so anfühlt, als sollte es).
Ich habe es getestet, um zu sehen, ob es funktioniert
Es scheint zu funktionieren! Das ist der Kern der Sache
.el {
background-image: -webkit-cross-fade(
url(image.jpg),
url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7),
50%
);
Das ist ein 1px transparentes GIF, Base64-kodiert.
Es funktioniert nicht in Firefox, aber in allen anderen Browsern. Außerdem kann man die Unterstützung direkt in CSS testen und etwas anderes tun, wenn dies nur eine Verbesserung ist.
@supports (background: -webkit-cross-fade(url(), url(), 50%)) {
/* Only apply the idea if supported, do the Firefox fallback outside of this */
}
Das ist im obigen Demo eingebaut.
Man könnte auch eine data:image/svg+xml URL verwenden, die
<image href="…" opacity="50%">enthält, obwohl die Größenanpassung problematisch sein kann und man keine benutzerdefinierten Eigenschaften verwenden und die Opazität potenziell animieren kann.Wenn Sie mit dieser Technik wirklich aufs Ganze gehen wollen und Hintergrundposition und -größe zurückbekommen möchten, könnten Sie HTML wie folgt in das SVG einfügen
Allerlei andere verrückte Dinge, die Sie tun könnten, wenn Sie wirklich wollten. Komposition hat die Angewohnheit, zu einigen ziemlich wilden Konsequenzen zu führen.
Wenn Sie ein paar Bytes sparen wollen, könnten Sie auch SVG verwenden
--transparent: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'/>");Ich würde eine CSS-Bild verwenden, um es noch kürzer und vielleicht auf den ersten Blick verständlicher zu machen
oooo, das scheint zu funktionieren. Das ist gut – ich mag auch die Verständlichkeit. Man könnte es so benennen:
--transparent-image-in-which-to-combine-with-others-to-fake-background-opacityFYI: Es gibt eine Spezifikation von css-images-4, die Folgendes erlauben würde:
image(transparent)Aber aus irgendeinem Grund haben Browser noch nicht viel von css-images-4 implementiert, obwohl es inzwischen über 5 Jahre alt ist.
https://www.w3.org/TR/css-images-4/#color-images
Tracking-Bug für die Implementierung in Firefox
https://bugzilla.mozilla.org/show_bug.cgi?id=1657516
LeaVerou hat kürzlich einen Vorschlag für eine @image-Syntax für css-images-5 gemacht, die eine CSS-Manipulation von Bildern vor der Verwendung in background usw. ermöglichen würde. Dies scheint die langfristige Lösung zu sein
https://github.com/w3c/csswg-drafts/issues/6807
Könnte dies als Lösung für Firefox funktionieren?
Es gibt eine Möglichkeit, die Opazität einer
background-Ebene zu steuern, aber sie ist nur in Safari verfügbar. Tatsächlich ist sie in Safari seit über einem halben Jahrzehnt verfügbar (schauen Sie sich das Datum dieses Artikels an!), aber kein anderer Browser hat sie seitdem implementiert.Ich spreche von der
filter()-Funktion. Diese nimmt ein Bild, jedes Bild, und einen CSS-Filter (in diesem Fall verwenden wiropacity()) und gibt das gefilterte Bild zurück (hier, das Originalbild, das semitransparent gemacht wurde).Hier ist ein Live-Test mit einem wiederholenden Gradienten auf dem
bodydahinter.