Gibt es eine Möglichkeit, CSS-Variablen mit url () zu interpolieren?

72

Ich möchte meine Hintergrund-URLs in benutzerdefinierten Eigenschaften (CSS-Variablen) speichern und sie mit der Hintergrundeigenschaft verwenden. Ich konnte jedoch keine Möglichkeit finden, die Zeichenfolge zu interpolieren, wenn ich sie als Parameter in verwende url().

Hier ist mein Beispielcode:

:root {
    --url: "https://download.unsplash.com/photo-1420708392410-3c593b80d416";
}

body {
    background: url(var(--url));
}

Ich weiß, dass dies mit der Interpolationsfunktion in Sass oder WENIGER problemlos möglich ist, aber ich bin gespannt, ob es eine Möglichkeit gibt, dies ohne Vorprozessor zu tun.

YashArora
quelle
4
Sie waren so nah,--url: url(yoururl); background: var(--url);
pol
7
@pol: Das ist überhaupt nicht nah. Damit fehlt der Punkt dieser Frage um eine Meile. Dennoch ist es ist die einzige Lösung für das Problem in Bezug auf url ().
BoltClock
@ SharmaJ Was für eine neue Antwort suchst du?
Temani Afif
2
@TemaniAfif Ich kann nicht ganz sicher sein, ob das OP den gleichen Sinn für die Frage hatte wie das, was mich hierher gebracht hat, aber ich hatte gehofft, dies zu tun: :root { --url: "https://example.com/images"; } body { background: url(var(--url)/bg1.jpg); } #wrapper { background: url(var(--url)/bg2.jpg); }Leider scheint es, als wäre ich entweder auf Javascript reduziert oder bearbeite eine Unmenge von Codezeilen zwischen Entwicklungs- und Produktionsumgebung. Naja.
Jay Irvine

Antworten:

96

Sie können die Interpolation mit den meisten CSS-Funktionen durchführen, einschließlich rgba()(siehe ein Beispiel hier ). Tatsächlich ist die Interpolation eines der Hauptmerkmale benutzerdefinierter Eigenschaften.

Sie können dies jedoch nicht tun url(), da url(var(--url))es nicht als url(Funktionstoken var(--url)gefolgt von einem ), sondern als einzelnes url()Token analysiert wird, das ungültig ist, da das var(--url)als URL selbst behandelt wird und nicht zitierte URLs in url()Token keine Klammern enthalten dürfen, es sei denn, sie werden maskiert . Dies bedeutet, dass die Ersetzung niemals tatsächlich erfolgt, da der Parser niemals var()Ausdrücke im Eigenschaftswert sieht - tatsächlich ist Ihre backgroundDeklaration vollständig ungültig.

Wenn Sie nichts davon verstanden haben, ist das in Ordnung. Sie müssen nur wissen, dass Sie die var()Interpolation url()aus alten Gründen nicht verwenden können .

Obwohl das in der Frage dargestellte Problem mit dem Legacy- url()Token zusammenhängt, können Sie dies nicht tun, indem Sie URL-Token aus mehreren var()Ausdrücken erstellen, falls Sie daran denken, etwas wie --uo: url(; --uc: );oder --uo: url("; --uc: ");und zu versuchen background: var(--uo) var(--url) var(--uc);. Dies liegt daran, dass benutzerdefinierte Eigenschaften keine nicht übereinstimmenden Zeichenfolgenbegrenzer oder Teile von url()Token enthalten können (sogenannte fehlerhafte URL-Token) .

Wenn Sie eine URL in einer benutzerdefinierten Eigenschaft angeben möchten, müssen Sie den gesamten url()Ausdruck ausschreiben und diesen gesamten Ausdruck ersetzen:

:root {
  --url: url("https://download.unsplash.com/photo-1420708392410-3c593b80d416");
}

body {
  background: var(--url);
}

Oder verwenden Sie stattdessen JavaScript var(), um die Interpolation durchzuführen.

BoltClock
quelle
8
Verstanden! @boltclock. Ich wusste nicht, wie url () analysiert und tokenisiert wird. Wenn jemand weiter lesen möchte, ist hier ein nützlicher Link - typedef-url-token .
YashArora
1
Danke für die tolle Antwort. So traurig, dass CSS-Designer diesen Anwendungsfall nicht angesprochen haben. :-(
MikeSchinkel
0

Ich hatte das gleiche Problem bei einem Projekt mit Cordova, also habe ich verwendet:

header{
  --bg-header: url(../img/header_home.png) left center/cover no-repeat;
  background: var(--bg-header,
      url("../img/header_home.png") left center/cover no-repeat
  );
}

Wenn Sie url ("") mit doppelten Anführungszeichen für die --var- Deklaration verwenden, funktioniert der Wert anscheinend nicht.

LucasTelesx
quelle