Допустим, я хочу реализовать переключение текста с помощью CSS, как описано в https://css-tricks.com/swapping-out-text-five- Different-ways/#aa-css-only-way:

:root {
    --release-version: "R0.0.0";
    --build-version: "v0.0.0";
}

/* https://css-tricks.com/swapping-out-text-five-different-ways/#aa-css-only-way */
#app-version {
    position: relative;
}
#app-version-checkbox {
    display: none;
}
#app-version-checkbox:checked + #app-version::after {
    content: var(--build-version);
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: white;
}
<input id="app-version-checkbox" type="checkbox">
<label for="app-version-checkbox" id="app-version">R0.0.0</label>

Который, как видите, работает.

Но я действительно хочу иметь возможность обновлять версии:

//TODO: get versions from a config file or something
let releaseVersion = "R1.1.0"
let buildVersion = "v1.32.0"

window.onload = () => {
    const root = document.querySelector(":root");
    root.style.setProperty("--release-version", releaseVersion)
    root.style.setProperty("--build-version", buildVersion)
    
    //cannot change label text with CSS
    document.querySelector("#app-version").innerHTML = releaseVersion
}
:root {
    --release-version: "R0.0.0";
    --build-version: "v0.0.0";
}

/* https://css-tricks.com/swapping-out-text-five-different-ways/#aa-css-only-way */
#app-version {
    position: relative;
}
#app-version-checkbox {
    display: none;
}
#app-version-checkbox:checked + #app-version::after {
    content: var(--build-version);
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: white;
}
<input id="app-version-checkbox" type="checkbox">
<label for="app-version-checkbox" id="app-version"></label>

И это не работает.

Итак, сначала я подумал, что я просто глуп, и я не должен использовать innerHTML, и это что-то сломало, но даже если я этого не сделаю:

//TODO: get versions from a config file or something
let releaseVersion = "R1.1.0"
let buildVersion = "v1.32.0"

window.onload = () => {
    const root = document.querySelector(":root");
    root.style.setProperty("--release-version", releaseVersion)
    root.style.setProperty("--build-version", buildVersion)
}
:root {
    --release-version: "R0.0.0";
    --build-version: "v0.0.0";
}

/* https://css-tricks.com/swapping-out-text-five-different-ways/#aa-css-only-way */
#app-version {
    position: relative;
}
#app-version-checkbox {
    display: none;
}
#app-version-checkbox:checked + #app-version::after {
    content: var(--build-version);
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: white;
}
<input id="app-version-checkbox" type="checkbox">
<label for="app-version-checkbox" id="app-version">R0.0.0</label>

Это все еще не работает.

Это акт установки переменных, который ломает приложение, и если я проверю фрагмент, я также замечу, что переопределение тоже странное:

overrides aren't set correctly

Я чувствую, что упускаю что-то очевидное, но я просто не вижу этого.

Что здесь происходит?

(И да, я понимаю, что, поскольку я все равно теперь использую JS, я мог бы просто использовать кнопку, но я хочу понять, почему это происходит.)

РЕДАКТИРОВАТЬ: выполнение этого с переменными CSS также позволило бы мне делать такие вещи, как

.release-version::after {
    content: var(--release-version);
}

Что было бы неплохо.

2
User1291 26 Янв 2022 в 14:29
1
Почему вы пытаетесь обновить текст с помощью переменных CSS?
 – 
Dominic
26 Янв 2022 в 14:32
Потому что в идеале я просто хочу обновить свойство, а затем распространить его везде, где оно используется - что html не позволяет, и выполнение всего в JS было бы проблемой, если бы я мог просто бросить класс на элемент и позволить CSS разобраться с этим , вместо. (см. редактирование)
 – 
User1291
26 Янв 2022 в 14:36
1
JS может легко изменить текстовое содержимое, скажем, любого элемента с заданным классом. Насколько это хлопотно, особенно по сравнению со временем, которое вы уже потратили на решение этой проблемы с CSS?
 – 
Chris G
26 Янв 2022 в 14:39
Я предполагаю, что это не просто замена let releaseVersion = "R1.1.0" let buildVersion = "v1.32.0" на let releaseVersion = """R1.1.0""" let buildVersion = """v1.32.0"""
 – 
Andrew Corrigan
26 Янв 2022 в 14:39
1
Вы потеряли кавычки, которые требуются свойству содержимого CSS, как видно из значений до их обновления. Поместите несколько кавычек в свою строку, и все должно быть хорошо.
 – 
A Haworth
26 Янв 2022 в 14:43

1 ответ

Лучший ответ

Переменные CSS копируются в том виде, в каком они есть, из того места, где они определены, в то место, где они используются. В основном это просто динамическое копирование и вставка, поэтому такие вещи работают:

:root {
   --color: 255,0,;
   --comma: ,;
}

div {
   color: rgba(var(--color) 5 var(--comma) 0.5);
}

Когда вы это сделаете:

root.style.setProperty("--release-version", releaseVersion)
root.style.setProperty("--build-version", buildVersion)

Это приведет к следующему:

:root {
   --release-version: R1.1.0;
   --build-version: v1.32.0;
}

Я имею в виду, что вы ожидаете, что root.style.setProperty("--color", "red") приведет к --release-version: red;, а не к --release-version: "red";. Но текст должен быть в кавычках, поэтому вам как-то нужно добавить кавычки вокруг текста.

Вы можете использовать JSON.stringify для преобразования строки в текстовое представление с необходимыми кавычками, что также позволит использовать " в содержимом значения:

//TODO: get versions from a config file or something
let releaseVersion = 'R1.1.0"'
let buildVersion = 'v1.32.0"'

window.onload = () => {
    const root = document.querySelector(":root");
    root.style.setProperty("--release-version", JSON.stringify(releaseVersion))
    root.style.setProperty("--build-version", JSON.stringify(buildVersion))
    
    //cannot change label text with CSS
    document.querySelector("#app-version").innerHTML = releaseVersion
}
:root {
    --release-version: "R0.0.0";
    --build-version: "v0.0.0";
}

/* https://css-tricks.com/swapping-out-text-five-different-ways/#aa-css-only-way */
#app-version {
    position: relative;
}
#app-version-checkbox {
    display: none;
}
#app-version-checkbox:checked + #app-version::after {
    content: var(--build-version);
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: white;
}
<input id="app-version-checkbox" type="checkbox">
<label for="app-version-checkbox" id="app-version"></label>
2
t.niese 26 Янв 2022 в 15:01
:facepalm: Да, теперь действительно очевидно. Большое спасибо!
 – 
User1291
26 Янв 2022 в 14:52
Многие проблемы очевидны, как только вы узнаете причину, по которой он не работает.
 – 
t.niese
26 Янв 2022 в 14:53