JS中的CSS,如何让props.className成为优先类

Posted

技术标签:

【中文标题】JS中的CSS,如何让props.className成为优先类【英文标题】:CSS in JS, how to make props.className the priority class 【发布时间】:2020-04-17 10:54:50 【问题描述】:

我们需要组件,其中作为 props 传递的类应该比默认类具有更高的优先级。

当将classes作为prop传递时,组件优先 在他自己的文件中创建的类。

Text.jsx

// this will be a component in another folder, it will be used in the whole app so it 
// should haveDYNAMIC styling
function Text(props) 
  const useStyles = makeStyles(theme => (
    default: 
      fontSize: 18,
      color: "black"
    
  ));

  const classes = useStyles();

  return (
    <div className=classNames(classes.default, props.className)>
      props.children
    </div>
  );

App.jsx

function App() 
  const useStyles = makeStyles(theme => (
    title: 
      fontSize: 80,
      color: "red"
    ,
    notGoodPractice: 
      fontSize: "80px !important"
    
  ));
  const classes = useStyles();

  return (
    <div className="App">
      <Text className=classes.title>Text in here is 18px</Text>
      <Text className=classes.notGoodPractice>
        Text in here is 80px
      </Text>
    </div>
  );

反应片段 => CodeSandBox

【问题讨论】:

CSS 没有“优先级”的概念。某些 CSS 选择器确实具有更高的优先级和选择性——但规则并不简单:tutorials.jenkov.com/css/precedence.html 这在正常优先级中很容易,我只需在 .css 文件的开头编写默认类,并在其下编写所有其他类:,真正的问题在于 CSS IN JS 这种方式很难做到,在 css 中它不掌握 classname 属性中的最后一个,当你定义 css 规则时,重要的是什么是最后一个。它与 spred 运算符或 Object.assign 不同。如果你想要的是将组件与样式解耦,然后注入样式以使其看起来像你想要的那样,我参考这篇文章:jobs.zalando.com/tech/blog/decoupled-styling-ui-components/… 您是否尝试过使用像 className=$classes.default $props.className 这样的字符串文字。我现在无法测试这个。但据我所知,我遇到了同样的问题并像这样使用它。 @RenaldoBalaj 是的,我也这么认为。很好奇解决方法,希望你能找到答案。 【参考方案1】:

您可以通过这种方式对作为 props 传递的类进行优先级排序。

请确保您没有在其上应用makeStyles,以便您可以在孩子中正确访问它们。

import React from "react";
import ReactDOM from "react-dom";
import  makeStyles  from "@material-ui/core/styles";

// this is how we will use the Text component
function App() 
  const style = 
    title: 
      fontSize: "80px",
      color: "red",
      "@media (max-width: 767px)": 
         color: "green"
      
    ,
    notGoodPractice: 
      fontSize: "80px"
    
  ;

  return (
    <div className="App">
      <Text class1=style.title>Title should be with size 80px</Text>
      <Text class1=style.notGoodPractice>Title should be with size 80px</Text>
    </div>
  );


// this will be a component in another folder, it will be used throw the in app so it should be as DYNAMIC as possible
function Text(props) 
  const useStyles = makeStyles(theme => (
    default1: 
      fontSize: 18,
      color: "black"
    ,
    priorityClass: props => props.class1
  ));

  const  default1, priorityClass  = useStyles(props);
  return <div className=`$default1 $priorityClass`>props.children</div>;


const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

查看实时沙盒https://codesandbox.io/s/zen-voice-mb60t

【讨论】:

我在演示中清楚地看到了, .notGoodPractice: fontSize: "80px !important" 认为它是一个库,每个人都应该添加 !important 来设置组件的样式吗?! 这就是我们已经实现的,但它似乎没有那么好扩展。假设我也需要添加阴影(仅在 1 种情况下),我们需要每天返回该组件。 + 您无法使用此解决方案进行 媒体查询 您可以在该场景中将单独的类仅传递给该组件 不管怎样,如果你按照正常的方式做,你会这样做 不要将它们传递给 makeStyles,这将是可扩展的解决方案

以上是关于JS中的CSS,如何让props.className成为优先类的主要内容,如果未能解决你的问题,请参考以下文章

html,如何让span中的文本不能被选择?

如何让 Tailwind.css 与 Gatsby.js 一起工作?

如何用CSS让文字居于div的底部

性能优化: CSS 和 JS 的装载与执行(一个网站在浏览器端, 是如何进行渲染的CSS+JS 渲染过程中的性能优化点)

性能优化: CSS 和 JS 的装载与执行(一个网站在浏览器端, 是如何进行渲染的CSS+JS 渲染过程中的性能优化点)

如何让 NGINX 提供静态内容,如 .js、.css、.html?