解决类名冲突2之css-in-js

205 阅读1分钟

css in js 的核心思想是:用一个JS对象来描述样式,而不是css样式表

例如下面的对象就是一个用于描述样式的对象:

const styles = {
    backgroundColor: "#f40",
    color: "#fff",
    width: "400px",
    height: "500px",
    margin: "0 auto"
}

由于这种描述样式的方式根本就不存在类名,自然不会有类名冲突

至于如何把样式应用到界面上,不是它所关心的事情,你可以用任何技术、任何框架、任何方式将它应用到界面。

vue、react都支持css in js,可以非常轻松的应用到界面

css in js的特点:

  • 绝无冲突的可能:由于它根本不存在类名,所以绝不可能出现类名冲突
  • 更加灵活:可以充分利用JS语言灵活的特点,用各种招式来处理样式
  • 应用面更广:只要支持js语言,就可以支持css in js,因此,在一些用JS语言开发移动端应用的时候非常好用,因为移动端应用很有可能并不支持css
  • 书写不便:书写样式,特别是公共样式的时候,处理起来不是很方便
  • 在页面中增加了大量冗余内容:在页面中处理css in js时,往往是将样式加入到元素的style属性中,会大量增加元素的内联样式,并且可能会有大量重复,不易阅读最终的页面代码

示例代码

(可直接复制下来浏览器打开)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div id="div1"></div>
    <div id="div2"></div>
    <script>
        /**
        * 给某个dom元素应用一或多个样式
        * @param {*} dom dom元素
        * @param {*} styles 样式对象
        */
        function applyStyles(dom, ...styles) {
            let targetStyles = {}; //最终合并的样式对象
            for (const style of styles) {
                targetStyles = {
                    ...targetStyles,
                    ...style
                }
            }

            for (const key in targetStyles) {
                const value = targetStyles[key];
                dom.style[key] = value;
            }
        }
        // 公共样式,可抽取到common.js
        const redBg = {
            backgroundColor: "#f40",
            color: "#fff",
        }
        
        // 函数
        function border(width = 2, color = "#333") {
            return {
                border: `${width}px solid ${color}`
            }
        }


        const div1 = document.getElementById("div1");
        const div2 = document.getElementById("div2");

        const styles = {
            width: "400px",
            height: "300px",
            margin: "0 auto"
        }

        applyStyles(div1, styles, border(), redBg)
        applyStyles(div2, styles, border(5, "green"))
    </script>
</body>
</html>

效果图