[Translation] CSS module-Future encoding method, css Encoding

Source: Internet
Author: User

[Translation] CSS module-Future encoding method, css Encoding
Preface

This is an article published by Glen Maddern in August 19, 2015. It is mainly mentioned in the previous translation article "Understanding CSS module methods". Now it is a good idea to follow up.

The translation here is based on my own understanding, so it is not just a sentence. What is wrong is inevitable and the level is limited. I hope you can point it out. Body

If you want to find a transformation point in the recent CSS development ideology, you 'd better go to Christopher Chedeau's "css in js" speech at NationJS in November 2014. This is a demarcation line. Different ideas are like high-speed particles that develop rapidly in their own direction. For example, writing Style, React Style, jsxstyle, and Radium in React and some projects that depend on React are three of the latest, most ingenious, and most feasible methods. If the invention is in an exploratory situation adjacent possibilities (adjacent possible), then christopher creates many close adjacent possibilities.

These problems exist in large CSS code libraries in different forms. Christopher pointed out that these problems may all be solved by writing code in js. However, this solution introduces its own complexity and features. You just need to take a look at how to process the range method in the hover state in the previously mentioned project (React Style, jsxstyle, and Radium. This problem has been solved in the browser-side css.

CSS Modules team finds the key to the problem-keep it consistent with CSS and write it in styles-in-js mode. Although we still insist on using CSS, we would like to thank our friends who have provided us with many suggestions.

We have been racking our brains to think about CSS and how to write it better. Step 1: Default local scope

In the css module, each file is compiled independently, so you can use some CSS short names-don't worry about naming conflicts. The following is an example of four states of the submit button.

Conventional CSS writing methods

Use Suit or BEM name, some CSS styles, and a piece of html. The Code is as follows:

Css code segment:

 

/* components/submit-button.css */

.Button { /* all styles for Normal */ }

.Button--disabled { /* overrides for Disabled */ }

.Button--error { /* overrides for Error */ }

.Button--in-progress { /* overrides for In Progress */

Html code segment:

 

<button class="Button Button--in-progress">Processing...</button>

The code above runs well. We have class names in four states, named BEM, avoiding the use of nested selectors. A word that starts with an upper-case letter.ButtonAs a selector to avoid conflicts with class names of previous or referenced styles. And we use-- ModifierSyntax to remove the basic style.

So far, this is a good piece of maintenance code. However, strict naming rules are also introduced. But this is also the best way to use standard CSS. CSS module Writing Method

With the CSS module, you don't have to worry about using some short names. It can be as follows.

 

/* components/submit-button.css */

.normal { /* all styles for Normal */ }

.disabled { /* all styles for Disabled */ }

.error { /* all styles for Error */ }

.inProgress { /* all styles for In Progress */

You don't have to add a long prefix anywhere. Why can we do this? Like other languages, we don't need to add a long prefix before the local variable, just change the file name corresponding to CSSSubmit-botton.css.

This can be used in JSRequireOrImportThe loaded CSS module file can be compiled.

 

/* components/submit-button.js */

import styles from './submit-button.css';

buttonElem.outerHTML = `<button class=${styles.normal}>Submit</button>`

The style name actually used on the page is the unique identifier dynamically generated. The CSS module compiles a file into an ICSS file, which facilitates communication between CSS and JS. When you run the program, you will get code similar to the following:

 

<button class="components_submit_button__normal__abc5436"> Processing...</button>

If a similar result is obtained, the operation is successful ~ Naming Conventions

Take the button as an example.

 

/* components/submit-button.css */

.normal { /* all styles for Normal */ }

.disabled { /* all styles for Disabled */ }

.error { /* all styles for Error */ }

.inProgress { /* all styles for In Progress */

All class names are independent, not the base class names, but others are used for modification.In the CSS module, all classes must include all attributes and styles.. This makes it very different when you use class names in JS.

 

/* Do not like this */

'Class =$ {[styles. normal, styles ['in-SS ss']. join ("")}'

/* The difference is that a separate class name is used */

'Class =$ {styles ['in-SS ss']}'

/* It is best to use the camper type */

'Class =$ {styles. inProgress }'

Of course, if you collect money based on the amount of code, you can continue with your approach. A React example

This is not a React-specific CSS module. However, React provides an excellent experience when using CSS modules. The following is a complex example.

 

/* components/submit-button.jsx */

import { Component } from 'react';

import styles from './submit-button.css';

export default class SubmitButton extends Component {

render() {

let className, text = "Submit"

if (this.props.store.submissionInProgress) {

className = styles.inProgress text = "Processing..."

} else if (this.props.store.errorOccurred) {

className = styles.error

} else if (!this.props.form.valid) {

className = styles.disabled

} else {

className = styles.normal

}

return <button className={className}>{text}</button>

}

}

You can use your style without worrying about global conflicts, so that you can focus on component development rather than writing styles. Once you switch between CSS and js frequently before leaving, you will not want to go back.

But this is just the beginning. When you consider style merging, the CSS module cannot be used again. Step 1: make everything a component

As mentioned above, the CSS module requires each State to contain all the required styles.

Let's assume that you need multiple States. Let's compare the CSS module and BEM naming.

 

/* BEM Style */

innerHTML = `<button class="Button Button--in-progress">`

/* CSS Modules */

innerHTML = `<button class="${styles.inProgress}">`

Wait, how do I share styles in all states? The answer is the most powerful tool of the CSS module-Components.

 

.common { /* all the common styles you want */ }

.normal { composes: common; /* anything that only applies to Normal */ }

.disabled { composes: common; /* anything that only applies to Disabled */ }

.error { composes: common; /* anything that only applies to Error */ }

.inProgress { composes: common; /* anything that only applies to In Progress */ }

KeywordsComposesNote. NormalInclude. CommonStyle in, just like the style in sass@ ExtendThe same keyword. Sass is implemented by rewriting the css selector. The css module is implemented by changing the class name used in js. SASS:

Use the BEM example above and use some SASS@ Extend

 

.Button--common { /* font-sizes, padding, border-radius */ }

.Button--normal { @extends .Button--common; /* blue color, light blue background */}

.Button--error { @extends .Button--common; /* red color, light red background */}

This will compile

 

.Button--common, .Button--normal, .Button--error { /* font-sizes, padding, border-radius */ }

.Button--normal { /* blue color, light blue background */ }

.Button--error { /* red color, light red background */ }

You only need to reference a class name on your tag to get a common and unique style. It is very powerful, but you must know that there are also special situations and traps. Hugo Giraudel summarized some issues. For more information, please click "Why should you avoid using SASS @ extend" to use the CSS Module

ComposesKeywords and@ ExtendThe usage is similar, but the working method is different. Let's look at an example.

 

.common { /* font-sizes, padding, border-radius */ }

.normal { composes: common; /* blue color, light blue background */ }

.error { composes: common; /* red color, light red background */ }

Will be compiled

 

.components_submit_button__common__abc5436 { /* font-sizes, padding, border-radius */ }

.components_submit_button__normal__def6547 { /* blue color, light blue background */ }

.components_submit_button__error__1638bcd { /* red color, light red background */ }

In js Code, import styles from "./submit-button.css" will get

 

styles: {
common: "components_submit_button__common__abc5436",
normal: "components_submit_button__common__abc5436 components_submit_button__normal__def6547", error: "components_submit_button__common__abc5436 components_submit_button__error__1638bcd"
}

Still useStyles. normalOrStryles. errorIn the DOM, multiple class names will be rendered.

 

<button class="components_submit_button__common__abc5436 components_submit_button__normal__def6547"> Submit</button>

This isComposesYou can merge multiple styles without modifying your JS Code or rewriting your CSS selector. Step 2. File Sharing code

Use SASS or LESS to work through@ ImportTo reference files in the same workspace. You can declare variables and functions and use them in other files. It is a good method, but variable names may conflict in different projects. Then you have to refactor your code and write it as shown inVariables. scssAndSettings. scssYou do not know which components depend on which variables. Your settings file will become very large.

There are also better solutions ("using Webpack to build smaller CSS"), but due to the global attributes of SASS, there are still a lot of restrictions.

The CSS module only runs a single file at a time, so it does not pollute the global scope. Js Code usageImportOrRequireReference dependencies, which is used by the CSS module.ComposeReference a style from another file.

 

/* colors.css */

.primary { color: #720; }

.secondary { color: #777; }/* other helper classes... */

/* submit-button.css */

.common { /* font-sizes, padding, border-radius */ }

.normal { composes: common; composes: primary from "../shared/colors.css"; }

Using components, we can referenceColors.cssFile class. In addition, the class name changed by the component will be changed in the output, but the CSS file itself does not change,ComposesThe block is also removed before the browser-side CSS is generated.

 

/* colors.css */
.shared_colors__primary__fca929 { color: #720; }
.shared_colors__secondary__acf292 { color: #777; }

 

/* submit-button.css */
.components_submit_button__common__abc5436 { /* font-sizes, padding, border-radius */ }
.components_submit_button__normal__def6547 {}

 

 

<button class="shared_colors__primary__fca929 components_submit_button__common__abc5436 components_submit_button__normal__def6547"> Submit </button>

In fact, on the browser side, normal does not have its own style. This is a good thing. You can add new semantic objects,No need to add CSS styles. We can do more,

Add class name and visual consistency during full-site development, and reduce the size of style code on the browser side.

Side note: You can use csso to detect and remove empty classes. Step 2: single responsibility Module

A component is powerful in describing what an element is without modifying its style. It maps page entities (elements) and style entities (style rules) in a different way ).

Look at an old CSS example.

 

.some_element { font-size: 1.5rem; color: rgba(0,0,0,0); padding: 0.5rem; box-shadow: 0 0 4px -2px; }

An element, some styles, very simple. In this case, there are still some problems: color, font-size, box-shadow, padding, which are all specified here, but cannot be used elsewhere.

Let's refactor it with SASS.

 

$large-font-size: 1.5rem;
$dark-text: rgba(0,0,0,0);
$padding-normal: 0.5rem;
@mixin subtle-shadow { box-shadow: 0 0 4px -2px; }
.some_element {
@include subtle-shadow;
font-size: $large-font-size;
color: $dark-text;
padding: $padding-normal;
}

It is much better than the old CSS style, but we have defined a very small part. In fact, like$ Large-font-sizeIs typographical,$ Padding-normalIs the layout. All of these expressions only express the meaning and won't run anywhere. If you want to declareBox-shadowVariable, but it does not express its own meaning, it must be used@ MixinOr@ Extend. Use the CSS Module

By using components, we can comment out which class names can be reused in the components.

 

.element {
composes: large from "./typography.css";
composes: dark-text from "./colors.css";
composes: padding-all-medium from "./layout.css";
composes: subtle-shadow from "./effect.css";
}

Use a file system instead of a namespace to divide styles for different purposes. Files that reference multiple single purposes will naturally appear.

If you want to reference multiple classes from a file, here is a simple method:

 

/* this short hand: */
.element {
composes: padding-large margin-small from "./layout.css";
}
/* is equivalent to: */
.element {
composes: padding-large from "./layout.css";
composes: margin-small from "./layout.css";
}

This allows you to correspond to a class name for each kind of vision in website development. Using the above method to develop your website becomes a possibility.

 

.article {
composes: flex vertical centered from "./layout.css";
}
.masthead {
composes: serif bold 48pt centered from "./typography.css";
composes: paragraph-margin-below from "./layout.css";
}
.body {
composes: max720 paragraph-margin-below from "layout.css";
composes: sans light paragraph-line-height from "./typography.css";
}

This is a technology that I am interested in further exploration. In my opinion, it combines the advantages of atomic CSS technology like Tachyons, the readability of Semantic UI style class names, and a single responsibility.

But the story of the CSS module has just begun. I hope you can use it now or in the future and spread it. Getting started

By using the CSS module, we hope to help you and your team, that is, you can exchange current CSS knowledge and products, and perform your work more comfortably and efficiently. We have tried to keep the syntax as simple as possible and have written some examples. When you can use the code in these examples, you can use it to work. Here are some demos about the Webpack, JSPM, and Browseriry projects. I hope this will help you. We have been checking which new environments can run the CSS module: it is adapting to NODEJS and Rails on the server side.

To make things easier, we have made a Plunkr here, which can be done directly without installation. Let's get started.

If you are ready to use it, you can take a look at the CSS Module source code. If you have any questions, you can discuss them in issue. CSS module groups are small in size and cannot cover all application scenarios.

We look forward to your discussion.

Wish: Happy writing style.

Original article: CSS Modules

Link: http://glenmaddern.com/articles/css-modules

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.