Значения CSS, не понятные браузеру, отбрасываются, что объясняет, почему -my-custom-property
был недоступен через .style
.
Раньше вам приходилось полагаться на хранение данных с атрибутами данных и самостоятельное наследование с помощью JavaScript.
Однако с тех пор «пользовательские свойства», то есть «переменные CSS», были введены в стандарт и реализованы браузерами, с поддержкой ~ 92% во всем мире на 2019-05-09 . На первый взгляд, Edge, похоже, был последним основным браузером, реализованным 16 октября 2017 года с версией 16.
По сути, вам нужно установить пользовательское свойство (например, --my-custom-property: 'foobar';
) для элемента, и к нему можно получить доступ что-то вроде getComputedStyle(your_el).getPropertyValue("--my-custom-property")
, которое вернет 'foobar'
(с начальным пробелом). Обратите внимание на начальные пробелы и кавычки. Он вернет значение в точности так, как оно было предоставлено.
Пример:
console.log(getComputedStyle(document.getElementById("a")).getPropertyValue("--my-custom-property-1"))
console.log(getComputedStyle(document.getElementById("b")).getPropertyValue("--my-custom-property-2"))
#b-div { --my-custom-property-2: 'world' }
<div style="--my-custom-property-1: 'hello'"><h1 id="a">#a 'hello'</h1></div>
<div id="b-div"><h1 id="b">#b 'world'</h1></div>
Вот несколько тестов с использованием одного и двух ведущих дефисов, наследования и различных методов получения значения:
function log(computed, selector, prop, value) {
let method = computed ? "getComputedStyle(el)" : "el.style"
let method_id = computed ? "computed" : "raw"
// Build first level of list (tag name)
let first = document.querySelector("#" + selector)
if (!first) {
first = document.createElement("li")
first.appendChild(document.createTextNode(selector))
first.setAttribute("id", selector)
first.appendChild(document.createElement("ul"))
document.querySelector("ul").appendChild(first)
}
// Build second level of list (method of style retrieval)
let second = document.querySelector("#" + selector + "-" + method_id)
if (!second) {
second = document.createElement("li")
second.appendChild(document.createTextNode(method))
second.setAttribute("id", selector + "-" + method_id)
second.appendChild(document.createElement("ul"))
first.querySelector("ul").appendChild(second)
}
// Build third level of list (property accessed)
let third = document.querySelector("#" + selector + "-prop" + prop)
if (!third) {
third = document.createElement("li")
third.appendChild(document.createTextNode(prop + ": `" + value + "`"))
third.setAttribute("id", "prop" + prop)
second.querySelector("ul").appendChild(third)
if (value === "") {
third.classList.add("bad")
} else {
third.classList.add("good")
}
}
}
// Uses .style
function getStyleAttr(selector, prop) {
let value = document.querySelector(selector).style.getPropertyValue(prop)
log(false, selector, prop, value)
}
// Uses getComputedStyle()
function getStyleComputed(selector, prop) {
let value = getComputedStyle(document.querySelector(selector)).getPropertyValue(prop)
log(true, selector, prop, value)
}
// Loop through each property for each element and output the value
let selectors = ["article", "h1", "p"]
let props = ["--my-custom-property", "-my-custom-property"]
selectors.forEach(function(selector) {
props.forEach(function(prop) {
getStyleAttr(selector, prop)
getStyleComputed(selector, prop)
})
})
code {
background: #eee;
padding: .2em;
}
.bad {
color: #800;
}
.good {
color: #080;
}
<article class="custom-prop-inheritance" style="--my-custom-property: 'foobar'; -my-custom-property: 'foobar'">
<h1>Title</h1>
<p>Custom properties require two leading hyphens (<code>-my-custom-property</code> <em>never</em> works). Using <code>el.style</code> does not support inheritance. To support both inheritance and custom properties, you must use <code>getComputedStyle(<b>el</b>)</code> along with two leading hyphens on the custom property (eg, <code>--my-custom-property</code>).</p>
</article>
<ul></ul>