列出 CSS 个自定义属性(CSS 个变量)
List CSS custom properties (CSS Variables)
我在样式表中设置了一些 CSS 自定义属性:
:root {
--bc: #fff;
--bc-primary: #eee;
--bc-secondary: #ddd;
}
如果我已经知道 CSS 变量的名称,我可以单独检索它们,如下所示:
console.log(getComputedStyle(document.body).getPropertyValue('--bc'));
// #fff
但是,如果我想提取 CSS 个变量及其值的列表,该怎么做?
一种可能的解决方案是解析 document.styleSheets
,然后将规则拆分为 properties/values
var allCSS = [].slice.call(document.styleSheets)
.reduce(function(prev, styleSheet) {
if (styleSheet.cssRules) {
return prev + [].slice.call(styleSheet.cssRules)
.reduce(function(prev, cssRule) {
if (cssRule.selectorText == ':root') {
var css = cssRule.cssText.split('{');
css = css[1].replace('}','').split(';');
for (var i = 0; i < css.length; i++) {
var prop = css[i].split(':');
if (prop.length == 2 && prop[0].indexOf('--') == 1) {
console.log('Property name: ', prop[0]);
console.log('Property value:', prop[1]);
}
}
}
}, '');
}
}, '');
:root {
--bc: #fff;
--bc-primary: #eee;
--bc-secondary: #ddd;
}
基于 LGSon's 这里有类似的内容,但使用 map
、filter
和 flat
以使其更易于逐行阅读。
const variables = [].slice.call(document.styleSheets)
.map(styleSheet => [].slice.call(styleSheet.cssRules))
.flat()
.filter(cssRule => cssRule.selectorText === ':root')
.map(cssRule => cssRule.cssText.split('{')[1].split('}')[0].trim().split(';'))
.flat()
.filter(text => text !== "")
.map(text => text.split(':'))
.map(parts => ({key: parts[0].trim(), value: parts[1].trim() }))
;
console.log(variables);
:root {
--foo: #fff;
--bar: #aaa
}
感谢@Ason 和@mvndaai。我个人喜欢这种格式:
const variables = [].slice.call(document.styleSheets)
.map((styleSheet) => [].slice.call(styleSheet.cssRules))
.flat()
.filter((cssRule) => cssRule.selectorText === ':root')
.map((cssRule) => cssRule.cssText.split('{')[1].split('}')[0].trim().split(';'))
.flat()
.filter((text) => text !== '')
.map((text) => text.split(':'))
.map((parts) => parts[0].trim() + ': ' + parts[1].trim())
;
console.log(variables.join('\n'));
:root {
--foo: #fff;
--bar: #aaa
}
在新的 Chrome 中,使用 Javascript 读取外部样式表可能会因 CORS 而中断。
有没有人知道解决这个问题的方法,如果没有,如果您使用 CDN,请将此作为警告。
这是一个过滤掉远程工作表的版本,因此您仍然可以获得本地样式我还使用 Array.from() 来提高可读性
var allCSSVars = Array.from(document.styleSheets)
.filter((styleSheet) => {
let isLocal = !styleSheet.href || styleSheet.href.startsWith(window.location.origin)
if (!isLocal) console.warn("Skipping remote style sheet due to cors: ", styleSheet.href);
return isLocal;
})
.map((styleSheet) => Array.from(styleSheet.cssRules))
.flat()
.filter((cssRule) => cssRule.selectorText === ':root')
.map((cssRule) => cssRule.cssText.split('{')[1].split('}')[0].trim().split(';'))
.flat()
.filter((text) => text !== '')
.map((text) => text.split(':'))
.map((parts) => {
return {key: parts[0].trim(), value: parts[1].trim()}
})
console.log("vars: ", allCSSVars)
//another way not sure whitch is best but the top way is looking promising
allCSSVars = [].slice.call(document.styleSheets)
.reduce(function (prev, styleSheet) {
try {
if (styleSheet.cssRules) {
return prev + [].slice.call(styleSheet.cssRules)
.reduce(function (prev, cssRule) {
if (cssRule.selectorText == ':root') {
var css = cssRule.cssText.split('{');
css = css[1].replace('}', '').split(';');
for (var i = 0; i < css.length; i++) {
var prop = css[i].split(':');
if (prop.length == 2 && prop[0].indexOf('--') == 1) {
console.log('Property name: ', prop[0]);
console.log('Property value:', prop[1]);
}
}
}
}, '');
}
} catch (e) {
console.warn("Skiping: ", e)
return [];
}
}, '');
:root {
--bc: #fff;
--bc-primary: #eee;
--bc-secondary: #ddd;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css@2/out/water.css">
这显示了没有 try 语句会发生什么,我无法快速转换这些密集的代码,所以使用了更传统的版本:)。
const variables = [].slice.call(document.styleSheets)
.map((styleSheet) => [].slice.call(styleSheet.cssRules))
.flat()
.filter((cssRule) => cssRule.selectorText === ':root')
.map((cssRule) => cssRule.cssText.split('{')[1].split('}')[0].trim().split(';'))
.flat()
.filter((text) => text !== '')
.map((text) => text.split(':'))
.map((parts) => parts[0].trim() + ': ' + parts[1].trim())
;
console.log(variables.join('\n'));
:root {
--foo: #fff;
--bar: #aaa
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css@2/out/water.css">
我在样式表中设置了一些 CSS 自定义属性:
:root {
--bc: #fff;
--bc-primary: #eee;
--bc-secondary: #ddd;
}
如果我已经知道 CSS 变量的名称,我可以单独检索它们,如下所示:
console.log(getComputedStyle(document.body).getPropertyValue('--bc'));
// #fff
但是,如果我想提取 CSS 个变量及其值的列表,该怎么做?
一种可能的解决方案是解析 document.styleSheets
,然后将规则拆分为 properties/values
var allCSS = [].slice.call(document.styleSheets)
.reduce(function(prev, styleSheet) {
if (styleSheet.cssRules) {
return prev + [].slice.call(styleSheet.cssRules)
.reduce(function(prev, cssRule) {
if (cssRule.selectorText == ':root') {
var css = cssRule.cssText.split('{');
css = css[1].replace('}','').split(';');
for (var i = 0; i < css.length; i++) {
var prop = css[i].split(':');
if (prop.length == 2 && prop[0].indexOf('--') == 1) {
console.log('Property name: ', prop[0]);
console.log('Property value:', prop[1]);
}
}
}
}, '');
}
}, '');
:root {
--bc: #fff;
--bc-primary: #eee;
--bc-secondary: #ddd;
}
基于 LGSon's map
、filter
和 flat
以使其更易于逐行阅读。
const variables = [].slice.call(document.styleSheets)
.map(styleSheet => [].slice.call(styleSheet.cssRules))
.flat()
.filter(cssRule => cssRule.selectorText === ':root')
.map(cssRule => cssRule.cssText.split('{')[1].split('}')[0].trim().split(';'))
.flat()
.filter(text => text !== "")
.map(text => text.split(':'))
.map(parts => ({key: parts[0].trim(), value: parts[1].trim() }))
;
console.log(variables);
:root {
--foo: #fff;
--bar: #aaa
}
感谢@Ason 和@mvndaai。我个人喜欢这种格式:
const variables = [].slice.call(document.styleSheets)
.map((styleSheet) => [].slice.call(styleSheet.cssRules))
.flat()
.filter((cssRule) => cssRule.selectorText === ':root')
.map((cssRule) => cssRule.cssText.split('{')[1].split('}')[0].trim().split(';'))
.flat()
.filter((text) => text !== '')
.map((text) => text.split(':'))
.map((parts) => parts[0].trim() + ': ' + parts[1].trim())
;
console.log(variables.join('\n'));
:root {
--foo: #fff;
--bar: #aaa
}
在新的 Chrome 中,使用 Javascript 读取外部样式表可能会因 CORS 而中断。
有没有人知道解决这个问题的方法,如果没有,如果您使用 CDN,请将此作为警告。
这是一个过滤掉远程工作表的版本,因此您仍然可以获得本地样式我还使用 Array.from() 来提高可读性
var allCSSVars = Array.from(document.styleSheets)
.filter((styleSheet) => {
let isLocal = !styleSheet.href || styleSheet.href.startsWith(window.location.origin)
if (!isLocal) console.warn("Skipping remote style sheet due to cors: ", styleSheet.href);
return isLocal;
})
.map((styleSheet) => Array.from(styleSheet.cssRules))
.flat()
.filter((cssRule) => cssRule.selectorText === ':root')
.map((cssRule) => cssRule.cssText.split('{')[1].split('}')[0].trim().split(';'))
.flat()
.filter((text) => text !== '')
.map((text) => text.split(':'))
.map((parts) => {
return {key: parts[0].trim(), value: parts[1].trim()}
})
console.log("vars: ", allCSSVars)
//another way not sure whitch is best but the top way is looking promising
allCSSVars = [].slice.call(document.styleSheets)
.reduce(function (prev, styleSheet) {
try {
if (styleSheet.cssRules) {
return prev + [].slice.call(styleSheet.cssRules)
.reduce(function (prev, cssRule) {
if (cssRule.selectorText == ':root') {
var css = cssRule.cssText.split('{');
css = css[1].replace('}', '').split(';');
for (var i = 0; i < css.length; i++) {
var prop = css[i].split(':');
if (prop.length == 2 && prop[0].indexOf('--') == 1) {
console.log('Property name: ', prop[0]);
console.log('Property value:', prop[1]);
}
}
}
}, '');
}
} catch (e) {
console.warn("Skiping: ", e)
return [];
}
}, '');
:root {
--bc: #fff;
--bc-primary: #eee;
--bc-secondary: #ddd;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css@2/out/water.css">
这显示了没有 try 语句会发生什么,我无法快速转换这些密集的代码,所以使用了更传统的版本:)。
const variables = [].slice.call(document.styleSheets)
.map((styleSheet) => [].slice.call(styleSheet.cssRules))
.flat()
.filter((cssRule) => cssRule.selectorText === ':root')
.map((cssRule) => cssRule.cssText.split('{')[1].split('}')[0].trim().split(';'))
.flat()
.filter((text) => text !== '')
.map((text) => text.split(':'))
.map((parts) => parts[0].trim() + ': ' + parts[1].trim())
;
console.log(variables.join('\n'));
:root {
--foo: #fff;
--bar: #aaa
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css@2/out/water.css">