[英]How to convert a JSON style object to a CSS string?
I wanted to set my element's style as such:我想这样设置元素的样式:
this.refs.element.style = {
...this.props.style,
background: 'blue',
};
But apparently you can't use an object to set the ref's style.但显然你不能使用 object 来设置裁判的风格。 I have to use a CSS style string with
;
我必须使用 CSS 样式的字符串
;
separating the prop:values
分离
prop:values
I'm aware that most people would set style in the render function, but for performance reasons, I can't repeatedly re-render.我知道大多数人会在渲染 function 中设置样式,但出于性能原因,我不能重复重新渲染。
A performant answer is to map
and join
the Object.entries
with semicolons:一个
Object.entries
答案是用分号map
和join
Object.entries
:
const style = {
...this.props.style,
background: 'blue',
};
const styleString = (
Object.entries(style).map(([k, v]) => `${k}:${v}`).join(';')
);
It unwraps background:'blue',
to background:blue;
它将
background:'blue',
到background:blue;
which works well for CSS这适用于 CSS
To replace any capital letter with dash lowercase letter用破折号小写字母替换任何大写字母
k = k.replace(/[A-Z]/g, match => `-${match.toLowerCase()}`);
this solution works in IE and handles camelCase keys like backgroundColor这个解决方案适用于 IE 并处理像 backgroundColor 这样的驼峰键
const style = { width: '1px', height: '1px', backgroundColor: 'red', transform: 'rotateZ(45deg)', } const styleToString = (style) => { return Object.keys(style).reduce((acc, key) => ( acc + key.split(/(?=[AZ])/).join('-').toLowerCase() + ':' + style[key] + ';' ), ''); }; console.log(styleToString(style)); // output - "width:1px;height:1px;background-color:red;transform:rotateZ(45deg);"
Use https://www.npmjs.com/package/json-to-css .使用https://www.npmjs.com/package/json-to-css 。 Note it will not add a semicolon to the last property to fix it you can beautify it with https://www.npmjs.com/package/cssbeautify Example
请注意,它不会在最后一个属性中添加分号来修复它,您可以使用https://www.npmjs.com/package/cssbeautify示例对其进行美化
const cssbeautify = require('cssbeautify')
const Css = require('json-to-css')
const json = {
"h1": {
"font-size": "18vw",
"color": "#f00"
},
".btn": {
"font-size": "18vw",
"color": "#f00"
}
}
const r = Css.of(json)
console.log(r)
const beautified = cssbeautify(r, {
autosemicolon: true
})
console.log(beautified)
Result结果
console.log src/utils/playground/index.spec.ts:22 // json-to-css
h1{font-size:18vw;color:#f00}
.btn{font-size:18vw;color:#f00}
console.log src/utils/playground/index.spec.ts:29 // cssbeautify
h1 {
font-size: 18vw;
color: #f00;
}
.btn {
font-size: 18vw;
color: #f00;
}
Adding to the great answer of @Artem Bochkarev添加到@Artem Bochkarev 的伟大答案
I'm adding a snippet to do the opposite conversion as well (string to object) which may come in handy to anyone stumbling here我正在添加一个片段来进行相反的转换(字符串到对象),这对在这里绊倒的人可能会派上用场
const style = { width: '1px', height: '1px', backgroundColor: 'red', transform: 'rotateZ(45deg)', }; const styleToString = (style) => { return Object.keys(style).reduce((acc, key) => ( acc + key.split(/(?=[AZ])/).join('-').toLowerCase() + ':' + style[key] + ';' ), ''); }; const stringToStyle = (style) => { const styles = {}; style.split(';').forEach((s) => { const parts = s.split(':', 2); if (parts.length > 1) { styles[parts[0].trim().replace(/-([az])/ig, (_, l) => l.toUpperCase())] = parts[1].trim(); } }); return styles; }; console.log(styleToString(style)); // output - "width:1px;height:1px;background-color:red;transform:rotateZ(45deg);" console.log(stringToStyle(styleToString(style)));
TL;DR: The problem is that you are overwriting the entire "style" property of the element and losing its prototype and methods. TL;DR:问题在于您正在覆盖元素的整个“样式”属性并丢失其原型和方法。 You must add your style object without change the entire property.
您必须在不更改整个属性的情况下添加样式 object。 If you want to apply an object-like style to a DOM element, just do:
如果你想将类似对象的样式应用于 DOM 元素,只需执行以下操作:
Object.assign(this.refs.element.style, {
background: 'blue',
color: 'white',
/** style properties:values goes here */
});
Explanation: The property "style" is an instance of the "CSSStyleDeclaration" interface.说明:属性“style”是“CSSStyleDeclaration”接口的一个实例。 If you overwrite the interface it wont be a "CSSStyleDeclaration" anymore.
如果您覆盖接口,它将不再是“CSSStyleDeclaration”。 It works when you set a string as value because javascript will pass the string directly to the element, without process anything.
当您将字符串设置为值时它会起作用,因为 javascript 会将字符串直接传递给元素,而不进行任何处理。
CSSStyleDeclaration Reference Doc: https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleDeclaration CSSStyleDeclaration 参考文档: https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleDeclaration
If you want to do a test, go to your navigator > inspector > console and paste the code below:如果你想做一个测试,go 到你的导航器 > 检查器 > 控制台并粘贴下面的代码:
const p1 = document.createElement('p');
p1.style = { color: 'blue' };
const p2 = document.createElement('p');
Object.assign(p2.style, { color: 'blue' });
console.log(p1);
console.log(p2);
The output will be: output 将是:
<p style=""></p>
<p style="color: blue;"></p>
the css
function in @material-ui/system
can help you out check more info here @material-ui/system
的css
函数可以帮助您在此处查看更多信息
import React from 'react';
import styled, { ThemeProvider } from 'styled-components';
import NoSsr from '@material-ui/core/NoSsr';
import { createMuiTheme } from '@material-ui/core/styles';
import { compose, spacing, palette, css } from '@material-ui/system';
const Box = styled.div`
${css(
compose(
spacing,
palette,
),
)}
`;
const theme = createMuiTheme();
export default function CssProp() {
return (
<NoSsr>
<ThemeProvider theme={theme}>
<Box color="white" css={{ bgcolor: 'palevioletred', p: 1, textTransform: 'uppercase' }}>
CssProp
</Box>
</ThemeProvider>
</NoSsr>
);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.