The purpose of this paper is to introduce the evolution of some design patterns and tools in the development of CSS in the 2018, by reviewing the historical background of CSS. Understanding these backgrounds will make it easier for you to understand each design idea and apply it. Now let's get started!
CSS has always been considered by web developers to be the simplest and hardest of a wonderful language. It's really easy to get started-you just have to define the style attributes and values for the elements, and it seems like the work you need to do is just as good! However, in some large projects, the organization of CSS is a complex and messy thing, you change the page of any element of a line of CSS style can affect the other elements on the page.
Starting with the simplest Web page index.html, this file contains a separate style file Index.css:
<! DOCTYPE html>
No class or ID is used in the HTML tag above.
In the absence of any CSS style, our site looks like this:
Click to view online demo
Features available, but not looking good, we can continue to add a bit of CSS in index.css to beautify the layout:
/* BASIC typography *//* from Https://github.com/oxalorg/sakura */html {font-size:62.5%; Font-family:serif;} body {font-size:1.8rem; line-height:1.618; Max-width:38em; Margin:auto; Color: #4a4a4a; Background-color: #f9f9f9; padding:13px;} @media (max-width:684px) {body {font-size:1.53rem; }} @media (max-width:382px) {body {font-size:1.35rem; }}H1, H2, H3, H4, H5, h6 {line-height:1.1; Font-family:verdana, Geneva, Sans-serif; font-weight:700; Overflow-wrap:break-word; Word-wrap:break-word; -ms-word-break:break-all; Word-break:break-word; -ms-hyphens:auto; -moz-hyphens:auto; -webkit-hyphens:auto; Hyphens:auto;} h1 {font-size:2.35em;} h2 {Font-size:2em;} h3 {font-size:1.75em;} h4 {font-size:1.5em;} h5 {font-size:1.25em;} h6 {font-size:1em;}
Most of this place is about typography (font, line high) style definitions, as well as some colors and a layout centering setting. In order for each attribute to have a reasonable value you need to learn the point design theory, but this place we use the CSS itself is not complex, you can directly define, the results are as follows:
Click here for See a live example
Something has changed! Just as CSS promises-adding a style to a document in a simple way doesn't require programming or complex business logic. Unfortunately, the reality is much more complicated, and we're not just using a simple style definition of CSS typography and color.
The layout of CSS uses
In the the 1990s, before the CSS was widely popularized, there was not much choice for the layout of the page. HTML was originally designed to create a plain text language, not a dynamic page with layouts such as sidebars, columns, and so on. In the early days, page layouts typically used HTML tables to organize content in rows and columns, but it worked, but the content and performance were a piece of cake, and if you wanted to change the layout of the page, you would have to modify a lot of HTML code.
The advent of CSS pushed the content (written in HTML) and performance (written in the CSS) of the separation, people began to remove all the layout code from the HTML into the CSS, it should be noted that the same as HTML CSS design is not used to do the layout of the content of the Web page, So it's hard to try to solve this kind of separation design in the early days.
Let's take a practical example to see how to implement the layout, reset the padding and margin before we define the CSS layout (which will affect the layout of the calculation), different areas we define different colors (do not care too much to look good and not see as long as the different areas are conspicuous enough)
/* RESET LAYOUT and ADD COLORS */body { margin:0; padding:0; Max-width:inherit; Background: #fff; Color: #4a4a4a;} Header, footer { font-size:large; Text-align:center; Padding:0.3em 0; Background-color: #4a4a4a; Color: #f9f9f9;} Nav { background: #eee;} Main { background: #f9f9f9;} Aside { background: #eee;}
Now the page should look like this:
Click here for See a live example
Next we use CSS to layout the content of the page, we will be in chronological order in three different ways, start with the most classic floating layout.
Floating-based layouts
The CSS float property was originally intended to float the picture to the left or right of a column of text (often seen in the newspaper). As early as the early 21st century, Web developers extended the benefits of this attribute to any element, meaning that you could create the illusion of travel and columns by floating the contents of P. Similarly, floats are not designed for this purpose, so there are many problems with compatibility.
In 2006, a List apart published a popular article in the Search of the Holy Grail, which outlines a detailed approach to the implementation of the Grail layout-a head, three columns of content and a bottom, and you must think a simple layout called the Grail layout is crazy, But in the time of pure CSS, it was really hard to achieve.
Here is an example based on a floating layout that uses some of the technical points mentioned in our article:
/* float-based LAYOUT */body { padding-left:200px; padding-right:190px; min-width:240px;} Header, footer { margin-left: -200px; Margin-right: -190px; } Main, Nav, aside { position:relative; Float:left;} Main { padding:0 20px; width:100%;} Nav { width:180px; padding:0 10px; right:240px; Margin-left:-100%;} aside { width:130px; padding:0 10px; Margin-right:-100%;} footer { Clear:both;} * HTML nav { left:150px;}
Take a closer look at the CSS code, in order for it to work with some necessary hack methods (negative margins, clear:both, hard-coded width calculations, etc.), we'll explain these details in more detail later. The final results are as follows:
Click here for See a live example
Looks good, but through the three columns of color can be seen that their height is different, the height of the page is not filled with the screen. These problems are caused by floating layouts, where all floats simply place the content on the left or right side of a block, but cannot know the height of the other blocks. This problem has not been a good solution until the Flexbox layout appears.
Flexbox-based layouts
The Flexbox CSS property was first presented in 2009, but was not widely supported by the browser until 2015. Flexbox is designed to define how a space is distributed on rows or columns, which makes it more suitable for layout than floating, which means that after more than 10 years of floating layouts, web developers are finally no longer using floating layouts with hack.
Here is an example based on the Flexbox layout. Note In order for the Flexbox to take effect we need to pack an extra p outside of the three columns:
<! DOCTYPE html>
Here is the CSS code for the Flexbox layout:
/* flexbox-based LAYOUT */body { min-height:100vh; Display:flex; Flex-direction:column;}. container { Display:flex; Flex:1;} Main { flex:1; Padding:0 20px;} Nav { flex:0 0 180px; padding:0 10px; Order:-1;} Aside { flex:0 0 130px; Padding:0 10px;}
This is more compact than a floating layout, although some of the flexbox properties and values seem somewhat confusing at first, but at least there is no need for a hack scheme with negative margins like floating layouts, which is a huge improvement. The final result is as follows:
Click here for a live example
The effect is much better! All columns are of the same height and occupy the height of the entire page. In a sense it seems to be perfect, but there are some minor problems with this approach, one of which is browser compatibility-the mainstream modern browsers support Flexbox, but some old browsers are incompatible. Fortunately, browser vendors are also doing their best to end support for older browsers, providing a more consistent development experience for web developers. Another problem is that we need to <p class="container">
wrap the HTML content tag, if we can avoid it will be more perfect. Ideally, no CSS layout needs to change the HTML tag.
The biggest drawback is that the CSS code itself--flexbox the floating hack, but the readability of the code becomes even worse. It's hard to understand Flexbox's CSS, and you don't know how to lay out all the elements on the page. When writing Flexbox layout code, there is a lot of time to rely on a lot of guessing and trying.
It is particularly important to note that Flexbox is designed to split elements in a single line or in a single column--it is not designed to be used to layout the entire page! Although it can be implemented well (much better than a floating layout). A different specification is used to handle multiple rows or multiple columns of layout, which we call CSS meshes.
Grid-based layouts
The CSS grid was first proposed in 2011 (not much later than the Flexbox proposal), but it took a long time to get popular on the browser. By the beginning of 2018, most modern browsers had already supported CSS grids (which was a huge improvement over a year or two ago)
Let's take a look at a grid-based layout example, and note that in this example we get rid of the restrictions that must be used in the Flexbox layout <p class="container">
, and we can simply use the original HTML and look at the CSS file:
/* grid-based LAYOUT */body { display:grid; MIN-HEIGHT:100VH; grid-template-columns:200px 1FR 150px; Grid-template-rows:min-content 1fr min-content;} header { grid-row:1; Grid-column:1/4;} Nav { grid-row:2; Grid-column:1/2; Padding:0 10px;} Main { grid-row:2; Grid-column:2/3; Padding:0 20px;} aside { grid-row:2; Grid-column:3/4; Padding:0 10px;} footer { grid-row:3; Grid-column:1/4;}
Although the results look like Flexbox-based layouts, the CSS has been improved to a great extent, clearly expressing the desired layout. The size and shape of rows and columns are defined in the body selector, and each item is defined directly by the location of the row and column they are in.
grid-column
This property may not be very well understood, it defines the starting and ending points of the column. This place is confusing to you maybe there are 3 columns, but why the scope of the definition is 1 to 4, through the following image you can understand:
Click here for See a live example
The first column is from 1 to 2, the second column is from 2 to 3, the third column from 3 to 4, so the head grid-column
is from 1 to 4 occupy the entire page, the navigation grid-column
is from 1 to 2 occupy the first column and so on
Once you get used to the grid syntax, you'll think it's a great way to make CSS layouts. The only downside is browser support, and fortunately the browser support has been further improved over the past year. As the first real layout tool designed for CSS is hard to describe its importance, in a sense, because existing tools require too much hack and workarounds to implement, web designers have historically been conservative in their creative layouts, The advent of CSS grids may spark a creative layout that has never been created-think it's exciting!
Extending CSS syntax using the CSS preprocessor
So far, we've introduced the basic style and layout of CSS, and now let's look at the tools that help CSS improve the language itself, starting with the CSS preprocessor.
The CSS preprocessor allows you to define styles in different languages, which will eventually help you translate into CSS that your browser can interpret, which is valuable when browsers are slow to support new features today. The first mainstream CSS preprocessor, released in 2006, provides a new, more concise syntax (indentation instead of braces, no semicolons, and so on), while adding some advanced features of CSS deletions, such as variables, tool methods, and calculations. Sass Here we use the SASS variable to implement the color-zone definition in the previous example:
$dark-color: #4a4a4a $light-color: #f9f9f9 $side-color: #eeebody color: $dark-color header, footer Background-color: $dark-color color: $light-color main background: $light-colornav, aside Background: $side-color
Note that we have $
defined reusable variables, omitting curly braces and semicolons, and the syntax looks clearer. The simplicity of the syntax makes sass look great, but the feature of the variable is more meaningful at the time, which opens up new possibilities for writing clean, maintainable CSS code.
Using sass you need to install Ruby (Ruby), the language is mainly to let Sass compiled into normal CSS, and you need to install Sass Gem, and then you can use the command line to convert your. sass file into a. css file, let's start by looking at a command line example:
Sass--watch Index.sass Index.css
This command periodically index.sass
changes the Sass code in the CSS into a index.css
file (the --watch
parameters are set to be monitored in real time.) Sass file change and compile, very convenient)
This process is called the build step. This is a very big hurdle in the 2006, and if you're familiar with programming languages like Ruby, this is a very simple process. But at the time many front-end developers used only HTML and CSS, and they didn't need a tool like this. Therefore, it is a big requirement for a person to learn the entire ecosystem in order to use CSS precompiled functionality.
At the time of 2009, the less CSS precompiled compiler was released. It is also written in Ruby, and offers a feature similar to sass, the key difference being that it's syntactically designed to be closer to CSS. This means that any CSS code is a legitimate less code, and we also look at an example of the syntax:
@dark-color: #4a4a4a; @light-color: #f9f9f9; @side-color: #eee; body { color: @dark-color;} Header, footer { background-color: @dark-color; Color: @light-color;} Main { background: @light-color;} Nav, aside { background: @side-color;}
The syntax is almost the same (the definition of the variable is used @
instead $
), but less and CSS have curly braces and semicolons, and the code without the sass example looks pretty. However, the similar features of CSS make it easier for developers to accept it, and in 2012, less used JavaScript (node. js) to rewrite the replacement of Ruby, which is faster than Ruby compiled, and many people who use node. js at work are more likely to get started.
To convert this code into a standard CSS, you need to install node. js and less and execute the following command line:
LESSC index.less Index.css
This command index.less
converts the LESSZ code in the file into a standard CSS code to the index.css
file, noting that the LESSC command cannot listen for changes in the file (unlike sass), which means that you need to install other auto-listening and compiling components to implement this function. Increases the complexity of the process. Again, it's not hard for programmers to use the command line, but it's a big hurdle for other people who just want to use the CSS precompiled compiler.
Drawing on less experience, sass developers released a new syntax called SCSS (a CSS superset similar to less) in 2010, while releasing Libsass, a C + + extension-based Ruby engine that makes compiling faster and adaptable to multiple languages.
Another CSS preprocessor is the 2010 release of Stylus, written in node. js, and more focused on clear syntax than sass or less. Usually the main CSS pre-compiler on these three kinds (sass,less,stylus), they are very similar in function, so you don't have to worry about choosing which one is wrong.
However, some people think that it is becoming more and more unnecessary to use the CSS preprocessor because the browser will eventually implement these functions (like variables and calculations). In addition, there is a method called CSS post-processor, which may make the CSS preprocessor obsolete (obviously there is some controversy), we will explain in detail later.
Conversion function of the processor after using CSS
The CSS post-processor uses JavaScript to parse and transform your CSS into legitimate CSS, which is similar to CSS preprocessor, and you can think of different ways to solve the same problem. The key difference is that the CSS preprocessor uses special syntax to mark the place where it needs to be converted, and the CSS post-processor can parse the standard CSS without needing any special syntax. As an example, let's take a look at the header tag style we originally defined:
H1, H2, H3, H4, H5, h6 { **-ms-hyphens:auto; -moz-hyphens:auto; -webkit-hyphens:auto;** Hyphens:auto;}
The attributes of the bold section become the vendor prefix, and the vendor prefix is a way for the browser vendor to experiment and test the new CSS functionality and to formally implement the prerequisites to provide developers with new CSS properties. -ms
on behalf of IE Browser, -moz
is the Firefox browser, -webkit
is based on the WebKit kernel browser.
It is annoying to define the prefix attributes of these different browser vendors, and to use the build tool to automatically add the vendor prefix as much as possible. We can use CSS preprocessor to do this, for example, we can use SCSS to achieve:
@mixin hyphens ($value) { -ms-hyphens: $value; -moz-hyphens: $value; -webkit-hyphens: $value; Hyphens: $value;} H1, H2, H3, H4, H5, h6 { @include hyphens (auto);}
This place uses the Sass mixin
function, you can define a block of CSS code and then reuse it anywhere else, and when the file is compiled into a standard CSS, all the @include
statements are replaced with the CSS in which they are matched @mixin
. Overall, this solution is not bad, but you still have to define a mixin for each CSS attribute that requires a vendor prefix, and these mixin definitions will require constant maintenance, such as when a browser supports a CSS property and you want to remove the attribute from your definition.
It is obviously more elegant to write CSS directly and then automatically identify the attributes that require a vendor prefix, rather than writing mixin. This is exactly what the CSS post-processor can do. For example, if you use the POSTCSS and Autoprefixer plug-ins, you can directly write the normal CSS does not need to specify the browser vendor prefix, the rest of the work is left to the processor to handle:
H1, H2, H3, H4, H5, h6 { hyphens:auto;}
When you use the CSS after the processor to run this code hyphens: auto;
will be replaced with all browser vendor prefix attributes, which means that you can normally write CSS do not worry about the various browser compatibility issues, it is not great!
In addition to POSTCSS plug-ins There are autoprefixer
many interesting plug-ins, Cssnext plug-ins can let you experience some of the experimental CSS new features, CSS modules can automatically change class name to avoid name collisions, Stylelint Can check out some of your CSS code definition errors and non-conformance specifications. These tools have been popular for the past year or two, providing developers with an engineering process they have never had before.
However, the development of the process always comes at a cost, and the installation and use of CSS post-processing is more complex than the CSS preprocessor. Not only will you install and execute the command line, you will also need to install and configure the various plugins and define the various complex rules (such as your target browser, etc.). Many developers are no longer running POSTCSS directly using the command line, but rather by configuring a few build systems like Grunt, Gulp, and Webpack, they can help you manage the various build tools that are needed in front-end development work.
It is worth noting that there is some controversy over the CSS post-processor, some people think that the term is a bit confusing (one argument is that the recommendation should be called the CSS preprocessor, there is a saying that should be referred to as CSS processor, etc.), some people think that with the CSS after the processor can completely do not need the CSS preprocessor, Some argue that both are used together. In any case, it is worthwhile to understand the use of the processor after the CSS.
Using CSS Design Patterns
CSS preprocessor and CSS post processors have made a huge improvement in the CSS development experience, but these tools alone are not enough to solve the problem of maintaining CSS code for large projects. To solve this problem, people have written guidelines on how to write CSS, often referred to as CSS specifications.
Before we dive into CSS specifications, it's important to figure out what makes CSS more difficult to maintain over time, and the key point is that CSS is global-every style you define is applied globally to every part of the page. A naming convention is used to guarantee the uniqueness of the class name or to have special rules that determine whether the specified style is applied to the specified element. The CSS specification provides an organized way to avoid these problems when there is a lot of code, so let's take a look at some of the mainstream specifications in chronological order.
Oocss
Oocss (Object-oriented CSS) was first introduced in 2009 and is a specification built around two principles. The first principle is the separation of structure and style, which means that the CSS that defines the structure (layout) should not be intermixed with CSS that defines the style (color, font, etc.), so that we can simply define a new skin for an application; the second principle is separating the container from the content and seeing the element as a reusable object. The key core point is that an object should look the same regardless of where it is used in the page.
OOCSS provides mature guidelines, but it is not explicitly stated for specific implementation specifications. The later SMACSS adopted its core concept and added more details to make it easier to use.
Smacss
SMACSS (CSS with extensible modular architecture) is a design pattern that emerged in the 2011, which divides CSS into 5 different categories-Basic specifications, layout specifications, modules, status specifications, and style specifications. SMACSS also has some recommended naming conventions, which are used as prefixes for layout specifications l-
layout-
, is-hidden
or as prefixes for status specifications is-collapsed
.
There is more detail in the specification than OOCSS,SMACSS, but it is a matter of careful consideration that CSS rules should be divided into which type of specification. The subsequent BEM improved on this aspect, making it easier to use.
BEM
BEM (block, element, modifier) is a specification that appeared in the 2010, and its idea is to cut the user interface into separate blocks. A block is a reusable component (such as a form search, which can be defined <form class="search-form"></form>
), an element that is part of a block cannot be reused individually (such as a button in a form search <button class="search-form__button">Search</button>
), a modifier is an entity that defines the appearance, state, or behavior of a block or element (such as disabling a search button, defined as <button class="search-form__button search-form__button--disabled">Search</button>
).
BEM's specification is easy to understand, and is also friendly to novice naming conventions, with the disadvantage of being able to cause class names to be very long and not follow the traditional naming conventions. Later, the atomic CSS brought this unconventional approach to a new height.
Atomic CSS
Atomic css (also known as functional CSS) is a specification that emerged in the 2014, and its idea is to create a small and functional single class based on a visual approach. This specification is the exact opposite of Oocss, Smacss, and BEM-it does not treat elements on the page as reusable objects, Atomic CSS ignores them, and each element uses a single, reusable set of class styles. So, like, <button class="search-form__button">Search</button>
it's been replaced with the same kind of notation.<button class="f6 br3 ph3 pv2 white bg-purple hover-bg-light-purple">Search</button>
If you see this example, the first reaction is to be intimidated, it's okay you're not the only one with the idea-many people think it's completely against CSS best practices, but the application of this controversial specification in different scenarios also produces a series of fascinating discussions. This article is a very clear analysis of the traditional idea of separation is that CSS relies on HTML creation (even if you use a specification like BEM), while the atomic way is that HTML relies on CSS creation, both of which are right, but think about it, you will find that the idea of a complete separation of CSS and HTML is not possible.
Other CSS design patterns, like CSS in JS, also contain the idea that CSS and HTML are interdependent, which has become one of the controversial design specifications.
CSS in JS
CSS in JS is a design pattern introduced in 2014, its core idea is to write CSS directly into the respective components, rather than a separate style file. This approach, introduced in the react framework, was the first to use inline styles, and later evolved into a way to use JavaScript to generate CSS and then insert it into the page's style label.
CSS in JS once again violates CSS's best practices for separation, mainly because the web has changed a lot over time. Initially, the web was mostly static--in which case the HTML content and the CSS representation were very meaningful, but now most of the applications are dynamic Web-building-in which case reusable components make more sense.
The goal of the CSS in JS design is to define boundaries that clearly contain the individual components of their html/css/js and are unaffected by other components. React was the first to adopt this idea, and the follow-up also affected other frameworks like angular, Ember and vue.js. It is important to note that the CSS in JS mode is relatively new, and developers are constantly trying to develop some CSS best practices for Web application components.
A variety of design patterns can easily overwhelm you, and the most important thing to remember is that there is no silver bullet.
Conclusion
In short, this is modern CSS. We introduced CSS basic layout styles, floating layouts, flexbox and grid layouts, and learned the new syntax provided by the CSS preprocessor for CSS, such as variables and mixins, as well as the conversion capabilities of the CSS post-processor, like adding a vendor prefix to the CSS. And some design patterns of CSS have overcome some problems of the global CSS. Here we have no time to dig more CSS other features, CSS coverage is too wide-any person who says it is simple may just smattering it!