A discussion of modularization from CSS

Source: Internet
Author: User
Tags naming convention
Modularity is a noun that we can hear everywhere today, what is modularity? Why do we need modularity? This is a question we need to figure out in this series of articles. We also take this part of the story, incidentally, to review the development of the front end.

To tell the truth, the topic of modularity is a bit large, I do not know where to start from where it is more appropriate, usually, the front-end work mainly involves three aspects: HTML, CSS, JS (JavaScript), and other like as (Actionscript,flash scripting language), JSP, Smarty, and so on template class syntax tag we omitted it here, because it is not particularly important. What we call the modular can also be used as the three lines to see, such as the HTML module, CSS Modular, and JS Modular, these three we call (the Web) front-end modularity, to understand the relationship between these, we have to understand the next thing is very clear.

As we stand alone, I want to start with CSS because this is the easiest piece of content that I think is easiest to start with.

Background

What did the first. css look like?

/* Index.css */body {  margin:0;  padding:0;  font-size:18px;}. box {  background: #333;  Color: #fff;}. box. list {  margin-left:10px;}. box. List. item {  border-bottom:1px solid #ccc;}. box. List. item:last-child {  border-bottom:0;}. Box list. Item a {  text-decoration:none;  Color: #fff;}. box. List. Item span {  color:red;}. Box list. Item A ... {  ...}

Is it familiar? A simple hand-hit list module.

The problem here is:

    • In this order, the selector will write longer, resulting in a cumbersome writing;


    • The increasingly long selector allows us to confuse the spatial order of the DOM, and imagine if there are several lateral selectors (such as. Box list. Item A and. Box list. Item span), we may not be able to see the relationship between the two, is it a parent or a sibling element?


    • Maintenance is difficult, suppose we need to refactor this box, add a layer between. box and. Wrap, and add a layer between. Item and a and span. block, that's a disaster, we have to be careful to find the exact location, and then find all the matching, long selectors, Make all modifications in the right place;


    • It's hard to reuse, assuming we need this box on another page, we'll need to copy and paste all of the box-related parts, and when the box needs to be modified, we might want to re-identify all the places where the box is used, and then copy and paste it--of course, Some people say that this problem can be solved by some means, we will discuss it later.

......

(Welcome to supplement CSS Development pain point)

As a matter of fact, the problems we encounter with CSS can be broadly summed up in the following points:

    • The selector is cumbersome and lengthy;


    • naming conflicts;


    • The hierarchy structure is not clear;


    • Code is difficult to reuse;

A lot of problems, how to solve? Because of the slow development of CSS, there has been no progress on the tools, resulting in these problems, such as the 1th above, almost no solution. So the problem often depends on the "norm" to solve. Let's take a look at code reuse first.

Multiplexing

To implement code reuse is simple, we just need to provide a public CSS library to store our public styles and public modules:

/* Common.css */body {  background: #fff;  Color: #333;  font-size:16px;}. Box ... {  background: #333;  Color: #fff;  ...}. Another-box ... {  ...}

Then we refer to this common.css in other CSS files, so that the code can be reused, as long as you want to share the global style and modules, just add it here.

<!--index.html--><! DOCTYPE html>

is perfect,

--at least so far, that's right.

Here are a few things we can explore:

    1. Assuming that our project is very large, there are about 20 pages so much, then each page we do will be added to the common inside a public style/module, then after the completion of the project, the volume of common may be larger than the size of other CSS;


    2. Suppose there are several such pages, they have very little content, such as 404 pages, may only need a small amount of public style, but due to maintenance problems, we still want to introduce common (separate write style will make the page in the common update when the update can not be synchronized), This makes a page become very "heavy";


    3. As the common more write, it occupies more names, then we introduce common, even if our page is nothing, but already by default is occupied a lot of naming, so that we have a page of the available naming less, and less and more;


    4. We write the public module in common, and write the private module in the private CSS of the specific page. Suppose now we need to add a public module globally. Nice-box, we found that the module name is already occupied in the index.css, so we try to change the name to. Handsome-box, but found that the name in the ABOUT.CSS is occupied, oh buy karma!

......

Suddenly the whole person is not good, the heart is full of despair, thinking or career change it, garbage language ruined my life.

Let us analyze that the above-mentioned cases actually focus on only two: first, redundancy; second, pollution. Redundancy is inevitable, in order to maintain a portion of flexibility is acceptable, but we need some way to reduce such redundancy, to avoid making it a burden, and pollution is a problem that needs to be solved, this time bomb will become an irreversible disaster as the project grows! The importance of naming conventions is now reflected.

This requires that we use a reasonable set of norms to constrain and organize our code.

Specification

The programming specification makes our project maintainable to a certain extent. For example, a naming convention is developed for the pollution of the class name, the specification of the writing selector is specified for the selector, and so on. These specifications constrain the writing of CSS to a certain extent, making the project not chaotic. NetEase's NEC is one of the more complete solutions. Interested in children's shoes can be searched to understand, the author itself by the NEC influence is larger, so the following content has a certain degree of similarity.

Now let's try to develop a set of CSS programming specifications to solve the above mentioned problems.

We stipulate that the page consists of only a few basic structures: frames, modules, and components. Other scattered elements, in addition to being an auxiliary class of modules, are not independent of those three.

Framework

A framework is the infrastructure that makes up a page, and it is the bones of a page. We assume that there is a page index.html, whose overall outermost representation is a class of. G-index p, which is then composed of three parts of the page header (. g-hd), body (. g-bd), footer (. g-ft):

<!--index.html--><! DOCTYPE html>

So we can probably paint a basic outline of a page. Then we'll add some modules to it.

Module

Module is the number of pages on the most, but also the most important part, it is the main part of code reuse, is a functional division of the area, such as navigation bar, Carousel Diagram, Login window, information list and so on, the modules are independent of each other, distributed on the page, embedded in the frame of the various positions, forming a colorful page.

As an example of index.html, we assume that the page header has a navigation bar module (. M-nav) with a news list module (. m-news) and a footer with a copyright notice module (. m-copy_right):

<!--index.html--><! DOCTYPE html>

Components

A component is a separate, reusable, and in some cases a fine particle that can be used as part of a module. such as a button, a logo and so on. In a sense, it can actually be equivalent to a module, because the difference between the two is only a different scale. The module emphasizes a fully functional whole, while the components emphasize independence.

We assume that this page also needs to put a logo (. u-logo) on the page and a login button (. u-login_btn) in the navigation bar:

<!--index.html--><! DOCTYPE html>

Three basic structure of the introduction, we come back to summarize. You must have found a phenomenon, in the framework of the frame, I give the framework element named with G, the module named using M-, the component name using U-. This is part of the naming convention, we use these three prefixes to the corresponding structure named, is to better mark a struct, better show its function, this is what we often say the semantics, but also to achieve the role of isolation, similar to the effect of the namespace.

    1. The name of the frame begins with G, which is generally the same as the page, such as index.html, and the framework is the outermost layer. G-index,about.html is. G-about, and so on, other commonly used internal structures are. G-HD (header),. G-BD (body),. g-ft (Footer),. G-SD (side),. G-MN (main), etc.;


    2. Module naming to M-beginning, generally in the corresponding use to name, such as navigation bar M-nav, news m-news, copyright m-copy_right, etc., in general, the module name is unique, and the module itself should be portable, reusable;


    3. Component naming starts with U, and is usually named by its own meaning, such as U-logo, which represents a logo,u-btn that represents a button.

In addition to the framework, modules, components of the relevant naming content, the naming convention has the following points:

    1. Name as far as possible abbreviated way, concise expression, such as with BD expression body, with NAV expression Navigator, and so on, use long words appear superfluous and bloated;


    2. Between the prefix and the name-the connection, and the name of a number of words with _, except the combination of words, such as side-menu;


    3. Z-start indicates state such as Z-active, Z-SUCC, z-disabled, etc.;


    4. You can customize other openings as needed, but try to keep the categories as small as possible, because too many classifications cause confusion and unnecessary classification overhead, in fact Gmuz can already meet the daily development.

Refactoring common

With the naming convention, we can make a rewrite of the common:

/* Common.css */body {  background: #fff;  Color: #333;  font-size:16px;}. M-nav {...}. M-news {...}. M-copy_right {...}

OK, now we have eased the "pollution" problem to a certain extent, at least according to the naming convention, our common constituted by the original general category, became now Gmuz four class, became more manageable and "not so easy to conflict", but it is far from solving the "pollution".

The following to facilitate the formulation, we call common.css "common", the corresponding page of the CSS, such as index.html-Index.css, about.html, about.css, called "Page CSS."

Here's a question that needs to be thought through: The properties of the module. Theoretically, a module should be public or private, assuming that a module is basically only possible on a certain page, or we do not intend to use it on other pages, we can say that this module is the private module of this page, such as the article page of the article List module (m-article_list), As well as the list element components (U-article_item) that make up this module, we can basically make sure that the two will not be reused on the other pages, so they are already default private properties, no need to put them in common, just put them on article.css. This can also artificially reduce the volume of common. So the question is, if the module can be stored in the common, but also can be stored in the page CSS, then we later in the common to add the public module, how to avoid the module name is already in the page CSS is occupied in the case? (4th of the above questions about the design of common)

I used to talk to a colleague about the issue of "subsequent additions to the public module naming conflict with other private modules", and finally we came to two solutions:

    1. By default, all modules are managed by common, and all modules default to public modules, and private modules are not allowed;


    2. For public modules, a single prefix cm-is used to differentiate, and all M-prefix modules are private modules.

The first scheme makes the common volume very large, and will always increase, not to be taken; the second scenario explicitly declares the module properties to avoid conflicts and is preferable.

And then it becomes:

/* Common.css */body {  background: #fff;  Color: #333;  font-size:16px;}. Cm-nav {...}. Cm-news {...}. Cm-copy_right {...}

And our private module is this:

/* Index.css */.g-index {  background: #fff;  Color: #333;  font-size:16px;}. M-nav {...}. M-news {...}. M-copy_right {...}

After this process, the naming conflict between our public and private modules is resolved, and there is no "a lot of class names are occupied" after a "nothing has been referenced common", because most of the content of common is cm module, And the page's own CSS can only have a private m module.

Obviously this scheme is feasible, but we will be more of a prefix, but also slightly ugly. But at the time of the hand playing CSS technology, we have no other better solution, this problem is here to settle. We solved the problem, but the method is not good enough, we will propose some better solutions when we mention the CSS preprocessing language.

OK, so let's think about the question: assuming we've finished the index page, and then we're going to write the About page, we found out that one of the modules in index m-news, we classified it as a private module, and now we actually need to use this module in about it, so , we return to the index page, the M-news module transferred from the INDEX.CSS to the Common.css, and renamed to Cm-news, and then back to the index page, and m-news related content (HTML, JS) are modified to cm-news. This is still in the circumstances we can realize, if the page is more, we have no idea which page has such a module, should not be promoted to a public module. One months later, the project was done one weeks ago, and now it needs to be followed up, with a more contact page, and then we find that this page uses a m-loc that we used to make a private module on the About page, so We went again. The process of raising public modules ...

Why is there such a problem? The root cause is that we cannot plan all the modules in advance, and we cannot clearly partition the properties of a module in the first place. This problem is basically no solution. The contradiction is that we have the private and Public property division of the module, but can not grasp all the module properties beforehand, can only take one step to calculate a step, the wrong will come back to change.

The solution to this problem is to remove the attribute partition of the module, all modules default to the public module, can be used at any time. But this is back to our previous situation, all the modules are m-*, and all together in the common, resulting in common volume is too large, so this problem can only be here.

Module

How to define a module? Or, how do you divide a piece of code into a single module? What is the basis of division? This is the question we are going to discuss next.

Design principles

We say that the module is a relatively independent and complete structure, in fact, this should be the concept of components, we are only from the scope of CSS to explore the modularity, then the definition of the module can be narrowed to: a (group) style is relatively independent and complete class. Like what:

/* copy_right */.m-copy_right {  color: #ccc;  Background: #666;  font-size:14px;  Text-align:center;  padding:20px 0;  line-height:1.8;} /* Nav */.m-nav {  color: #ccc;  Background: #666;  font-size:14px;}. M-nav. U-logo {...}. M-nav. List {...}. M-nav. List. Item {...}

In principle, a CSS module should follow these requirements:

Exposing only one class name to the outside;

/** * Correct demonstration, all module related code is hung in the module selector name */.m-nav {...}. M-nav. List {...}. M-nav. List. Item {...} /** * Error demonstration, exposing the. M-nav and. List two class names, polluting the space */.m-nav {...}. List {...}. List. Item {...}

Does not affect the surrounding layout: In general, try not to use a layout that is out of the document flow (using the float:left/right,position:absolute/fixed layout) and try not to use margin. This is to make the module more stable, with higher plasticity;

/** * Correct demonstration, define a module in common, locate and offset the module in the page CSS *//* common */.u-logo {  width:100px;  height:100px;}. cm-news {  width:200px;  height:100px;} /* Index */.u-logo {  position:absolute;  left:20px;  top:20px;}. cm-news {  margin-top:50px;}
/** * Error demonstration, define a module in common and fix its position *//* common */.u-logo {  width:100px;  height:100px;  Position:absolute;  left:20px;  top:20px;}. cm-news {  width:200px;  height:100px;  margin-top:50px;}

Module as far as possible to facilitate the reuse of the magnitude, to avoid chatty, refinement;

<!--index.html--><! DOCTYPE html>
<!--index.html--><! DOCTYPE html>

      

It is important to note that the principle 3rd here is not just for CSS modularity, but in fact it is more suitable for modular design ideas, which we will refer to when we talk about component later.

Inherited

The inheritance of CSS is also very simple, in general there are several ways:

    1. In CSS and write two classes, such as. Cm-nav,. M-nav, we know that this is equivalent to having two (group) classes share a set of styles, and then we can supplement the. M-nav separately to achieve inheritance and customization;


    2. In the class attribute and write two classes, such as


    3. Referencing a class directly in the page CSS
      And then supplement the style to implement customizations such as. cm-nav {margin-bottom:20px;} ;

......

(There are many black magic, welcome to add)

The first kind in our pattern is not desirable, because our public modules are placed in the common, it is not possible to go up every inheritance to fill a class;
The second is desirable, but requires a more approximate class name, not advocated;
The third kind is simple and reliable.

/* Common.css */body {  background: #fff;  Color: #333;  font-size:16px;}. Cm-nav {  width:100%;  height:50px;  Color: #fff;  Background: #333;}

We can use this in the page CSS:

/* Index.css */.g-index {  background: #fff;  Color: #333;  font-size:16px;}. Cm-nav {  width:1000px;  /* Style Overlay */  Margin:auto;  /* Style Add */}

State

When we talk about prefixes above, we mention a prefix Z, which we say can be used to represent states. A module can have a state, of course, here is not a good state of the meaning of the bad state (the module has become refined ~), here refers to a variety of forms, we, for example, a pop-up module M-dialog, it should have at least two states: show and Hide (Close). We use the keyword active to represent these two states, and add the Z-active class to represent the display without hiding. As follows:

/* Index.css */.m-dialog {    display:none;}. m-dialog.z-active {    display:block;}
<!--index.html--><! DOCTYPE html>

Pop-up window a more representative example, another typical example is the button, used bootstrap people know that the button btn only need to add a few state classes, you can have a different color scheme, to cope with different scenarios need, which is actually our Z-meaning. Z is very common, we should design our modules to meet a variety of predictable needs, rather than every time on the page to customize and cover the basic style.

Summarize

So far, we have customized a set of standard-based CSS modular production methods, although not perfect, but this is a simple, 0 tools, 0 cost solution, for any project.

We can see that the so-called modularity, in fact, is a subset of the normalization, through the formulation of a set of norms, only to produce the module. So the CSS module process is actually the CSS normalization process.

In fact, because the CSS itself is not a language, does not have the language characteristics, we can only use other means and tools to achieve the purpose of modularity. So far, we have just stayed in the normative constraints, the content looks relatively low:), no matter, the next section we will begin to introduce the "CSS preprocessing language of the modular practice." To know, for already accustomed to sass programming me, is also stuffy a big tone finally wrote here ...

Presumably you also notice that the text of the "hand-play CSS" This argument, in fact, this is just a traditional CSS programming way of a joke, to tell the truth what kind of programming is not hand-hit, difficult to use feet? Ha ha. But to tell the truth, with CSS preprocessing, modularity can be a real meaning of modularity, the significance of modularity is highlighted, because all of our thinking and efforts, tricks, the ultimate goal is only one-to improve work efficiency.

Notice

The appearance of CSS preprocessing language is a very important stage, it has directly promoted the development of CSS and changed the way CSS has been programmed for a long time.

Let's take a peek at SASS:

Index.scss@import './common/normalize '; @import './common/common '; @import './common/mixin ';. G-index {  @include m-nav;  @include m-news;  @include m-copy_right;  . G-HD {    . m-nav {      width:100px;      Margin:auto;    }  }  . G-BD {    . m-news {      margin-top:20px;    }  }  . g-ft {    . m-copy_right {      width:100px;      Margin:auto;}}}  

Sass Selectors nesting is not a bright blind eye? Is it convenient to import files directly? and a variable? can also write functions???

In the next section, "The modular practice of CSS preprocessing language" We look at how CSS preprocessing languages make modularity better.

Related Article

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.