I’m currently working on a blog project that uses Tailwind as a CSS framework. For an introduction to Tailwind, please refer to my other post:

In 2021, it's time to try to write CSS Tailwind framework for https://juejin.cn/post/6935725712737304613Copy the code

But how do we better organize tailwind styles in our code? How to play to its strengths and avoid its weaknesses?

That is the subject of this article.

Compare several programming methods

1. Traditional HTML code

In traditional development, style introduces an external style sheet for a single tag or other, and a corresponding class in the Html tag through the class attribute.

<head>
  <style>
  	.classA {
    	color: # 000;
    }
  </style>
</head>
<body>
	<span class="classA">Hello World!</span>
</body>
Copy the code

Inadequate:

  1. Repeated use of the same attributes, large code redundancy.
  2. Too scattered classes, difficult to manage, simply speaking of the name is a headache, and the wrong name is also a common situation.
  3. There are duplicate names, no namespaces.

2. CSS in JS

With the advent of the idea of modularity, styles are nested within component modules.

Of course, in React, style is often written within an object of a component, which is also known as CSS in JS.

We introduce the style object via the component style property:

const style = {
  'color': 'red'.'fontSize': '46px'
};

const clickHandler = () = > alert('hi'); 

ReactDOM.render(
  <h1 style={style} onclick={clickHandler}>
     Hello, world!
  </h1>.document.getElementById('example'));Copy the code

CSS modules are already supported by mainstream packaging tools, and we can achieve this by introducing external styles.

Note that modular CSS returns an object with a class name map as a key

import style from './style.css'

const clickHandler = () = > alert('hi'); 

ReactDOM.render(
  <h1 className={style.AclassName} onclick={clickHandler}>
     Hello, world!
  </h1>.document.getElementById('example'));Copy the code

Advantages:

  1. Modular style, naming does not conflict, exist in their own namespace

    Repetition is actually avoided by adding a hash suffix to the style class name in the module.

  2. The code is relatively well organized

Inadequate:

  1. Similar to traditional coding, same thingCSSThe code still needs to be written in classes
  2. Code redundancy

3. Atomic class: Official Tailwind case

This is the official example of tailwind overrewriting

! []

This is actually a bit similar to writing traditional atomic classes, but the difference is that some of these functional classes are combinations of atomic classes, such as:

.bg-white {
  --tw-bg-opacity: 1;
  background-color: rgba(255.255.255.var(--tw-bg-opacity));
}
Copy the code

In fact, atomic classes were often criticized in the early days

  1. Without well-organized code, too many classes are thrown together and difficult to debug
  2. The same style, although abbreviated, still needs to be written in multiple element tags, which is redundant
  3. tailwindThe class itself has a lower priority and is difficult to style overlay if we use other component frameworks in our project

How did I write tailwind in React

  1. First, I chose to organize the code in a modular way. The difference is that here we use className for style introduction:

    const classMap = {
    	chatNotification: "p-6 max-w-sm mx-auto bg-white rounded-xl shadow-md flex items-center space-x-4".chatNotificationLogoWrapper: "flex-shrink-0".chatNotificationLogo: "h-12 w-12"
        
    <div className={classMap.chatNotification}>
      <div className={classMap.chatNotificationLogoWrapper}>
        <img className={classMap.chatNotificationLogo} src="/img/logo.svg" alt="ChitChat Logo">
      </div>
    </div>
    Copy the code

    This organizes the code style on the one hand and improves the reusability of the style of elements of the same type on the other.

  2. Style extension using template strings

    If the conditions are not met and we need to expand on classMap, we can use template strings.

    Here’s an example:

        <img class= {`${classMap.chatNotificationLogo} h-14 w-14`} src="/img/logo.svg" alt="ChitChat Logo">
    Copy the code

    This will cover the tailwind pattern.

  3. Override the default style of the component framework

    If we need to override the default styles of component libraries such as ANTD, the priority of atomic classes alone is definitely not enough, and we need to introduce external styles to override.

    Here you can write tailwind files in an external stylesheet using @apply:

    .menu li {
    	@apply text-base;
    }
    Copy the code

    To prevent namespace collisions, remember to enable the CSS Module in the packaging tool:

    import styles from './style.css'
    
    const classMap = {
    	menu: "flex flex-col justify-start items-center"
    }
    
    // Remember that modular CSS returns class name objects
    <Menu className={`${classMap.menu} ${styles.menu}`} / >Copy the code

    Attention! Using @apply in an external stylesheet simply introduces styles into the stylesheet, and there is still code redundancy

    So if you can, write the style to a classMap object and reference it in a className.

  4. Extend the tailwind style

    In fact, this part is similar to the third point, for hover, dynamic effect Transform, tailwind can not finely generate classes, after all, each animation needs are different.

    This can be supplemented by external stylesheets to write appropriate styles.

conclusion

  1. Use modularity to preserve a list of class names for code organization
  2. Reduce use in external styles@apply
  3. Concatenate a list of class names using template strings.
  4. Override component library styles, improve priorities, or extend functionality by using external reference stylesheets.

That’s all I have to say about writing CSS code with tailwind in React.

Refer to the article

CSS Module nguyen other www.ruanyifeng.com/blog/2017/0…

Tailwind tailwindcss.com/docs/utilit official document…