CSS Module
If you want to know the recent turning point in CSS, you should choose to watch Christopher Chedeau's share of CSS in JS at the November 2014 NATIONJS Convention. It must be said that this is a technological watershed moment, a group of different thinking in their own direction like particles into the high-energy vortex in the same rapid development. Among them, writing CSS styles in React or React related projects, React style, Jxstyle and Radium are three of the newest, best and most feasible methods. If "invention" is an example of the closest possible possibility (translator note: The closest possible is a concept presented by Steven Johnson in 2010), then Christopher is to make a lot more likely to get closer (the translator notes: Two of the three tools above are from his share).
These are the issues that exist in many large CSS code libraries. Christopher pointed out that as long as your style through the use of JS to manage, these problems can be well solved. It has to be said that it does make sense, but this approach has its complexities and leads to other related issues. In fact, just look at how the browser handles :hover
pseudo-class state, we will find that some things in the CSS actually very early solved. The CSS module team feels we can solve the problem more rationally: we can continue to keep the CSS as it is now and build more reasonable improvements on the basis of the STYLES-IN-JS community. Although we have found a solution and defended the original beauty of CSS, we still owe our gratitude to those who have pushed us to this result. Thank you, friends! Let me explain to you what a CSS module is and why it is the future.
The first step: as a local without having to consider global conflicts
- The first step: as a local without having to consider global conflicts
- How did we do it before the CSS module?
- What do we do when the CSS module comes out?
- Naming conventions
- React Example
- Step Two: Components are everything
- Step three: Inter-file sharing
- Fourth step: function Single module
- Roll it! CSS Module!
In a CSS module, each file is compiled into a separate file. So we just need to use the generic simple class selector name. We don't have to worry about it polluting the global variables. Next I'll write a four-state button to illustrate this feature.
How did we do it before the Https://jsfiddle.net/pqnot81c/embedded/result/CSS module?
We might use the SUIT/BEM naming convention to name the style so that our HTML and CSS code looks like this:
/* 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 */
It looks like it's pretty good. Using the BEM command allows us to have 4 style variables so that we do not have to use a nested selector. Using Button
This initial capitalization method can be a good way to avoid conflicts with previous code or other dependent code. In addition, we used the --
syntax to clearly show our dependency Class. In general, this can make our code easier to maintain, but it requires a lot of effort in the naming conventions. But this is already the best solution that CSS can give at the moment. What do we do when the CSS module comes out?
The CSS module means that you never have to worry about your name too much, just use the name you feel is the most meaningful:
/* 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 */
Please note that we do not use button
this word anywhere. But in turn, why must we use it? This file has been named submit-button.css
! Since in other languages you don't need to prefix your local variables, there's no reason to add this crappy feature to CSS. It require
import
is possible to compile a CSS module by using or importing files from JS.
/* components/submit-button.js */import styles from "./submit-button.css";buttonElem.outerHTML = `<button class=${styles.normal}>Submit</button>
You do not have to worry about the name of the public will cause a naming conflict, after compiling the actual class name is automatically generated and guaranteed to be unique. CSS module for you to do everything, eventually compiled into a CSS and JS interactive ICSS
suffix file (read here to learn more). So your program might end up looking something like this:
<button class="components_submit_button__normal__abc5436"> Processing...</button>
If your class name becomes similar to the example above, congratulations on your success!
Naming conventions
Now go back and take a closer look at our sample code:
/* 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 */
Note that all classes are independent of each other, there is no " base class " and then other classes integrate and " overwrite " Its properties in this case. Each class in a CSS module must contain all of the styles required by this element (detailed later). This makes it a lot different when you use the style in JS:
/* Don"t do this */`class=${[styles.normal, styles["in-progress"]].join(" ")}`/* Using a single name makes a big difference */`class=${styles["in-progress"]}`/* camelCase makes it even better */`class=${styles.inProgress}`
Of course, if your salary is calculated according to the length of the string, you can do what you like. React Example
CSS modules are not unique to React, but it is much more fun to use CSS modules in React. For this reason, I think it is necessary for me to show the following example of a slippery silky:
/* 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 don't have to worry about your class naming conflicts with global style sheet naming, so you can focus more on the component than on the style. I'm sure that once you've used it, you'll never want to go back to the original pattern. But this is just the beginning of everything. CSS modularity is your basic, but it's time to think about how to put your styles together. Step Two: Components are everything
I mentioned above that each class must contain all the styles of the button in different states, and the code may differ from the BEM naming method as follows:
/* BEM Style */innerHTML = `<button class="Button Button--in-progress">`/* CSS Modules */innerHTML = `<button class="${styles.inProgress}">`
So the question is, how do you share your style in all the state styles? The answer is the powerful weapon- component of the CSS module:
.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 */}
composes
This keyword will .normal
.common
include all the styles within the class, which is a bit like the syntax of Sass @extends
. But Sass relies on rewriting your CSS file to achieve the effect, and the CSS module will finally be compiled by JS compiler export, no need to modify the file (Translator Note: The following will be described in detail). Sass
In accordance with the BEM naming convention, the words I write with Sass @extends
may resemble the following code:
.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 */}
The compiled CSS file looks like this:
.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 can just need a class to tag your elements <button class="Button--error">
, but you can get all the styles that include both common and special cases. This looks really great, but you need to be aware that this syntax has problems and pitfalls in some special situations. Hugo Giraudel in his article to do a very good summing up, thank him! CSS Module
composes
The syntax looks very similar @extends
but the way they work is different. To illustrate, 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 */ }
The compiled file may be as follows:
.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 */ }
The JS code import styles from "./submit-button.css"
is eventually returned by:
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"}
So we can still use style.normal
or style.error
in our code, there will still be multiple class styles rendered on our DOM .
<button class="components_submit_button__common__abc5436 components_submit_button__normal__def6547"> Submit</button>
This is where the composes
syntax is, and you can mix the styles of your elements with different classes without rewriting your CSS. Step three: Inter-file sharing
In Sass or less, you can share styles in each file using @import
the global work interval. This allows you to define a variable or function () in a file mixins
and share it in your other component files. It's good to do this, but soon your variable name will conflict with the other variable names (although it's in a different space), you'll inevitably refactor your variables.scss
or settings.scss
, finally, you'll find that you don't understand which component depends on which variable. At the end of the final you will find your profile variable name redundant to become very impractical. There is still a better solution to the problem (in fact Ben Smithett's article Sass and Wepack's mixed use gives the CSS module a lot of inspiration, I recommend you read this article), but no matter how you do it is confined to the Sass of the global environment. The CSS module runs only one file at a time, which avoids contamination of the global context. And like JS using import
or require
to load dependencies, CSS modules are used compose
to load 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 are able to drill down into each colors.css
of the same basic style sheets and rename it as you like. And because the component simply changes the name of the last exported class, not the CSS file itself, the composes
statement is deleted before the browser resolves.
/* 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, when it is parsed by the browser, we don't have a "normal" style in our part. This is a good thing! This means that we can add a local name to a meaningful object (probably called "normal") without adding code to the CSS file. The more we use, the less visual errors and inconsistencies in the user's browser are caused to our site. Off-topic: Empty class styles can be checked for removal using tools such as Csso. Fourth step: function Single module
The component is very powerful because it does let you describe what an element is, not what it consists of those styles. This is a different way to describe the mapping between conceptual examples ( elements ) to style entities ( style rules ). Let's look at a simple CSS example:
.some_element { font-size: 1.5rem; color: rgba(0,0,0,0); padding: 0.5rem; box-shadow: 0 0 4px -2px;}
These elements, styles are particularly simple. However, there are also problems: color, font size, box shading, padding-everything here is tailor-made, which makes it difficult for us to reuse these styles in other places . Let's refactor these code 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;}
This is an evolutionary version, but we only achieve part of the goal. In fact $large-font-size
and $padding-normal
only in the name of the expression of its purpose, and can not be carried out anywhere. box-shadow
There is no way to assign values to variables like this definition, we have to use mixin
or @extends
grammar to match. CSS Module
By using components, we can define our components using the parts we can reuse:
.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";}
This type of writing is bound to have a lot of single-function files, but it is much better to use a file system to manage different uses of a style than a namespace. If you want to import multiple class styles from a file, there's a simple way to do this:
/* 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 opens up the possibility of using very fine-grained class styles to define some style aliases to use for each site:
.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";}
I am very interested in this technology, I think, it mixes like tachyons similar CSS atom technology, like the Semantic UI as the variable separation of readable benefits (Translator Note: The name of the CSS module is simple to understand, the component reuse convenient). But the path to CSS modularity is just the beginning, and in the future we want you to try more to write a new chapter for it. Roll it! CSS Module!
We want CSS modularity to help you and your team maintain your code based on your existing CSS and products, making it more comfortable and efficient. We have approached the possibility to minimize the extra syntax and try to make sure that the syntax and the existing changes are small. We have sample code for Webpack, JSPM and browserify, and if you use one of them, you can refer to one or two. Of course we are also looking for a new environment for the use of CSS module sessions: Support for NodeJS is ongoing, and Rails support has been put on the agenda. But in order to make it easier, I made a preview example on the Plunker, you can run it without installing anything: here is the Github warehouse address of the CSS module, if you have any questions, please open issue to ask. CSS Module team is still very small, we have not seen some useful examples, you are welcome to contribute to us.
Finally, I wish everyone happy writing style, happy every day!
Original: Http://glenmaddern.com/articles/css-modules
This article link: http://www.75team.com/post/1049.html
--EOF--
Posted in 2015-08-21 20:34:48 , last modified on 2016-03-15 16:31:48
? "Text" aggregation, scatter animation with the node. JS Development Wall Concise tutorial? Comments
? 2016-odd Dance group blog-www.75team.com
Powered by ThinkJS & Firekylin
Go CSS Module