CSS architecture goals: prediction, reuse, expansion, and maintenance

Source: Internet
Author: User
Tags css preprocessor

Web developers who are good at CSS can not only copy prototype objects visually, but also use code for perfect presentation. You do not need to use tables or images as few as possible. If you are a real master, you can quickly apply the latest and greatest technologies to your projects, such as media queries, transitions, filters, and conversions. Although these are all possessed by a real CSS expert, CSS is rarely discussed separately or evaluated by someone.

Interestingly, we seldom comment on other languages like this. Rails developers do not think they are good developers because their code is more standardized. This is just a benchmark. Of course, his code must be standardized. In addition, you need to consider other aspects, such as whether the code is readable? Is it easy to modify or expand ......

These are all natural issues. CSS is no different from them. Today's web applications are larger than ever. A lack of well-thought-out CSS architecture often weakens development. It is time to evaluate the CSS architecture, just like evaluating other languages, these should not be taken into consideration after the event or simply belong to the designers.

1. Good CSS architecture goals

In the CSS community, it is difficult to propose a best practice that has become a general consensus. Judging from the comment on Hacker News and the developers' response to the CSS lint release, most people disagree with the basic CSS things. Therefore, instead of laying a set of basic arguments for your best practices, you should determine the true goals.

A good CSS architecture goal is not the same as developing a good application. It must be predictable, reusable, maintainable, and scalable.

Predictable

Predictable means you can regulate your behavior as expected. When you add or modify a rule, it does not affect unspecified parts. For a small website, some minor changes are nothing. For large websites with thousands of pages, prediction is necessary.

Reusable

CSS rules should be abstract and decoupled, so that you can quickly build new components on the existing basis without re-modifying the encoding mode.

Maintenance

When a new component is placed on a website and added, modified, or redesigned, the existing CSS does not need to be reconstructed, and the newly added X does not break the Y component of the original page.

Scalable

When the website grows to a certain scale, it must be maintained and expanded. Scalable CSS means that the CSS architecture of a website can be easily managed by individuals or teams without the need to spend too much learning.

2. Common error practices

Before achieving a good CSS architecture goal, let's look at some common mistakes, which is good for us to achieve our goal.

Although the examples below can be executed well, they will bring you a lot of troubles. Although our intentions and aspirations are good, these development modes will cause you a headache.

Almost every website has a specific virtual element that looks exactly the same as other pages, except for only one page. In the face of such a situation, almost every novice CSS developer (or even experienced) will modify it in the same way. You should find something special (or create it yourself) for the page, and then write a new rule to operate it.

Modify components based on parent Components

  1. . Widget {
  2. Background: yellow;
  3. Border: 1px solid black;
  4. Color: black;
  5. Width: 50%;
  6. }
  7.  
  8. # Sidebar. widget {
  9. Width: 200px;
  10. }
  11.  
  12. Body. Homepage. widget {
  13. Background: white;
  14. }

At first glance, this is definitely a harmless code, but let's see if it has reached the goal we set.

First, Widgets are unpredictable in examle. When these widgets appear on either side of the page or on the home page, developers expect them to be displayed in a specific way, without losing their unique features. In addition, it cannot be reused or expanded.

In addition, it is difficult to maintain. Once this widget needs to be re-designed, You have to modify several other CSS styles. Imagine that if the code is written in other languages, it is basically a class definition, and then the class definition is used and extended in another part of the code. This directly violates the open/close principle of software development.

Software entities (classes, modules, functions, etc.) should be open to extensions and closed to modifications.

Overly Complex Selector

Occasionally, some articles introduce CSS selectors that play a very important role in the presentation of the entire website, and claim that no class selector or ID selector is required.

However, the deeper the development, the more I will stay away from this complicated selector. The more complex a selector is, the more coupled it is with HTML. By using HTML tags and aggregator, you can keep the HTML code clean, but make CSS more gross and messy.

  1. # Main-nav ul Li Div {}
  2. # Content Article H1: First-child {}
  3. # Sidebar> div> H3 + P {}

A simple understanding of the above Code. The first option may be to style the drop-down menu. The second option is to indicate that the title of the article should be different from the H1 element on other pages; the last one indicates adding some extra space in the sidebar of the first section.

If the HTML remains unchanged, nothing can be said, but it is unrealistic. An overly complex selector is impressive. It can help HTML get rid of the complexity on the surface, but it is useless to achieve a good CSS architecture goal.

The examples mentioned above are not predictable, reusable, scalable, and maintainable. For example, in the first selector (down menu) example, if a drop-down list with very similar appearances needs to be used on different pages, and # Main-nav does not belong to internal elements, so do you need to redesign? Assume that the developer wants to modify part of the DIV tag in the third example, the entire rule will be broken.

Too common class name

When creating reusable design components, it is common to overwrite the child elements of the accessories in the class selector of the components. For example:

  1. <Div class = "widget">
  2. <H3 class = "title">...
  3. <Div class = "contents">
  4. Lorem ipsum dolor sit Amet, consectetur adipiscing elit.
  5. In condimentum Justo et est dapibus sit Amet euismod ligula ornare.
  6. Vivamus elementum accumsan dignissim.
  7. <Button class = "action"> click me! </Button>
  8. </Div>
  9. </Div>
  1. . Widget {}
  2. . Widget. Title {}
  3. . Widget. Contents {}
  4. . Widget. Action {}

Child element class selectors such as. Title,. Contents, And. action can be safely named by styles without worrying that these styles will spread to other elements with the same class name. This is indeed true. However, it does not prevent the same style class name from spreading to this component.

In some large projects, names such as. title may be used on another page or itself. If this happens, the entire title is obviously different from expected.

Too common class selector names can cause many unpredictable CSS styles.

A Rule does too many things

Sometimes, you need to create a 20pixels visualization component in the upper left corner of the website.

  1. . Widget {
  2. Position: absolute;
  3. Top: 20px;
  4. Left: 20px;
  5. Background-color: red;
  6. Font-size: 1.5em;
  7. Text-transform: uppercase;
  8. }

Next, you need to use this component in other areas of the website. The code above is obviously incorrect and cannot be reused.

The key to the problem is that you have made the. widget selector do too many things, not only specifying the position of the component, but also styling its appearance and feeling. The appearance and feeling can be general, but the position is not. Sometimes, integrating and using them reduces the cost.

Although this seems harmless, copying and pasting has become a habit for some inexperienced CSS programmers. If a new team needs a specific component, such as. infobox, they will try to use this class selector. However, if the information box is not displayed as expected, it is displayed correctly in each required area. What do you think they will do? In my experience, they will break the reusable rule. On the contrary, they will simply copy and paste the code to every desired place. Do unnecessary repetitive work.

3. Cause

The common error practices listed above have a similarity, and the CSS style bears too much.

You may be surprised to say that, after all, it is a style sheet. Shouldn't it take on most (if not all) styles? Isn't that exactly what we want?

Indeed. But in general, things are not that simple. Separation of content and representation is a good thing, but CSS independence from HTML does not mean that the content also needs to be separated from the representation. In other words, if CSS requests analyze the HTML architecture in depth, splitting all the display code from the HTML does not necessarily achieve all goals.

In addition, HTML rarely contains only the content, which also indicates the overall framework. In general, the architecture contains the iner element, allowing CSS to isolate some fixed elements. Even if there is no presentational classes, you can mix HTML to clearly display the content.

I believe that, in view of the current HTML and CSS status, it is very necessary to combine HTML and CSS wisely as a presentation layer. The content layer can also be separated by templates and partial templates.

4. solution.

If HTML and CSS are combined as the presentation layer of a web application, they need to adopt some methods to better promote the formation of excellent CSS architecture.

The best way is to include as few HTML architectures as possible in CSS. CSS defines the visual effect of an element, no matter where it is. If some specific components need to display different effects on different occasions, they should be given different names. For example, CSS defines a button component through the. Button class selector. If HTML wants a button that looks like a specific element, you can use. Button. If there are special requirements, the buttons here are different from others (which may be larger and wider), then CSS needs to define a new class, HTML can use a new class to give the element a new visual effect.

CSS gives external features to elements. html calls are made on the page. Less CSS can be called by more HTML architectures.

Accurately declaring elements in HTML not only clearly express the design intent, but also allows other developers to clearly view the markup and understand what the elements will look like. Without this practice, it is difficult to distinguish whether the appearance setting of an element is intentional or unintentional, which can easily lead to confusion in the team.

Filling in a large number of classes in a tag is a common defect, which often requires additional effort. A css style can be referenced thousands of times for a specific component. So, in order to display the declaration in the mark, is it really worth repeating this class?

Although this fear is valid, it may be misleading. The implication is that no matter whether you use a parent selector in CSS or write thousands of classes by yourself, there will be some additional options here. Viewing the same level of abstraction in rails or other frameworks can maintain a good visual appearance in HTML, without having to write the same class over and over again in the class.

5. Best practices.

I have summarized the above errors and made some suggestions based on my own experience. I hope they can help you better achieve your CSS architecture goals.

Focus

The best way to ensure that selector does not apply irrelevant styles to some elements is not to give them a chance. For example, selectors such as # Main-nav ul Li Div may be easily applied to unwanted elements. On the other hand, selectors like. subnav won't give them any chance. It is the best way to apply the class selector directly to the elements you want, and to maintain element predictability.

  1. /* Grenade */
  2. # Main-nav ul Li ul {}
  3.  
  4. /* Sniper rifle */
  5. . Subnav {}

Modular

A well-organized Component layer can help solve the loose coupling between HTML architecture and CSS. In addition, the CSS component itself should be modular. Components should know how to style and work better, but there should not be too many assumptions about layout, positioning, and their relationship with the surrounding elements.

In general, CSS should define the component appearance, rather than the layout or position. We also need to follow the principles when using background, color, and font attributes.

The layout and position should be composed of a separate layout class or a separate container element (remember to effectively separate the content from the display is actually to separate the content from the container ).

Namespace for Classes

We have checked why the parent selector cannot play a 100% role in blocking and preventing cross style contamination. A better solution is to apply the namespace on the class. If an element is a member of a visualization component, each child element of the element should use a namespace-based component.

  1. /* High risk of style cross-contamination */
  2. . Widget {}
  3. . Widget. Title {}
  4.  
  5. /* Low risk of style cross-contamination */
  6. . Widget {}
  7. . Widget-title {}

Namespace for Classes ensures component independence and modularity. It can minimize existing class conflicts and reduce some special requirements of child elements.

Create modifier class to expand Components

When an existing component needs to be different in a specific context, you can create a modifier class to expand it.

  1. /* Bad */
  2. . Widget {}
  3. # Sidebar. widget {}
  4.  
  5. /* GOOD */
  6. . Widget {}
  7. . Widget-Sidebar {}

As we can see, to modify components based on the disadvantages of the parent element, we need to reiterate that a modifier class can be used anywhere. Location-Based overwriting can only be used in a specific location. modifier classes can also be used multiple times as needed. Obviously, modifier Classes meet the needs of HTML developers.

Organize CSS into a logical structure

Jonathan Snook mentioned in his outstanding smacss that CSS can be divided into four different classes: Base, layout, and modules) and status ). The basic concept includes the reset principle and element default values. The layout is to locate the elements within the site range and act as a general layout assistant like the grid system; the module is a reusable visual element; the status refers to the style, which can be enabled or disabled through JavaScript.

A component is an independent visual element. On the other hand, a template is a building block. Templates rarely describe the vision and feeling from their own perspectives. On the contrary, they are single and reusable models that can be put together to form components.

To provide more detailed examples, a component may be a mode dialog box. This mode may contain a gradient website signature in the header, or may have shadow around it, a close button in the upper right corner, and the position is fixed between the vertical and horizontal lines. These four modes may be used repeatedly by the website. Therefore, you rarely think of re-encoding and design. All these templates form a module component.

Style and style usage

A person with a large website may have such experience. An HTML element with a class may have no idea about its purpose. You want to delete it, but you are hesitant, because you may not be aware of its role. Once such a thing occurs over and over again, there will be more and more such classes in the project over time, only because the team members do not dare to delete it.

In front-end web development, classes take too many responsibilities, so this problem occurs. Styles HTML elements, playing the Javascript hook role, function detection, and automated testing. When so many applications are using classes, it will be very difficult for you to delete them from HTML.

However, using mature conventions can completely avoid this problem. When you see a class in HTML, you should understand its purpose immediately. I recommend that you use a prefix. For example, Add. js to JavaScript to indicate that modernizr classes can be prefixed with. supports.

In this way, it is very easy to find unused classes and remove them from HTML. You can even automatically complete this process by cross-referencing the document. stylesheets object in HTML in JavaScript. If no such class is found in document. stylesheets, it can be safely removed.

In general, the best practice is to separate the content from the demo, and to separate the functions is equally important. Using style classes like JavaScript hooks can deepen the coupling between CSS and JavaScript to some extent, but it is difficult or impossible to change the appearance without breaking the functionality.

Logical naming class

Most CSS writers prefer to use hyphens to separate naming words, but the hyphens are not enough to distinguish classes of different types.

Nicolas Gallagher recently wrote a solution for the problem and achieved great success (slightly changed). To illustrate the naming conventions, consider the following format:

  1. /* A component */
  2. . Button-Group {}
  3.  
  4. /* A component modifier (modifying. Button )*/
  5. . Button-Primary {}
  6.  
  7. /* A component sub-object (lives within. Button )*/
  8. . Button-Icon {}
  9.  
  10. /* Is this a component class or a layout class? */
  11. . Header {}

From the above class, we can find that it is difficult to correctly distinguish the type rules. This is not only confusing, but it is also difficult to automatically test CSS and HTML. A structured naming convention should be able to know the relationship between its class name and other classes at first glance, and know its location in HTML-making naming easier and easier to test.

  1. /* Templates rules (using sass placeholders )*/
  2. % Template-name
  3. % Template-name -- modifier-name
  4. % Template-name _ Sub-Object
  5. % Template-name _ Sub-object -- modifier-name
  6.  
  7. /* Component Rules */
  8. . Component-name
  9. . Component-name -- modifier-name
  10. . Component-name _ Sub-Object
  11. . Component-name _ Sub-object -- modifier-name
  12.  
  13. /* Layout Rules */
  14. . L-layout-Method
  15. . Grid
  16.  
  17. /* State rules */
  18. . Is-state-type
  19.  
  20. /* Non-styled JavaScript hooks */
  21. . Js-action-name

Redo the first example:

  1. /* A component */
  2. . Button-Group {}
  3.  
  4. /* A component modifier (modifying. Button )*/
  5. . Button -- primary {}
  6.  
  7. /* A component sub-object (lives within. Button )*/
  8. . Button _ icon {}
  9.  
  10. /* A layout class */
  11. . L-header {}

6. Tools

Maintaining an efficient and well-organized CSS architecture is very difficult, especially in large teams. We recommend several good tools to help you manage your website's CSS architecture.

CSS Preprocessor

The CSS Preprocessor is written in PhP5. Common Features of The Preprocessor help you quickly compile CSS. In addition, some pre-processors known as "functions" do not actually play a good role in the CSS architecture. I will provide a list below, which must be avoided during use:

  • Do not nest rules purely for organizing code. You can only output the CSS you really want.
  • Do not use Mixin when parameters are not required. Mixin without parameters is more suitable for use as a template and is easy to expand.
  • Do not use @ extend on the selector. It is not a single class. From the design point of view, it is meaningless. It will expand the compiled CSS.
  • When using the component modifier rules, do not use the @ extend UI component, which will lose the basic chain.

@ Extend and % placeholder are two excellent features in the Preprocessor. They help you easily manage CSS abstractions without adding bloat and a large number of base classes to CSS and HTML. Otherwise, they will be difficult to manage.

When you use @ extend for the first time, it is often used with the modifier class, for example:

  1. . Button {
  2. /* Button styles */
  3. }
  4.  
  5. /* Bad */
  6. . Button -- primary {
  7. @ Extend. Button;
  8. /* Modification styles */
  9. }

This will cause you to lose the inheritance chain in HTML. It is difficult to use JavaScript to select all button instances.

As a general rule, I seldom extend the UI component or do something after knowing the type. This is a way to differentiate between templates and components. templates do not need to be involved in the application logic and can be extended securely using pre-processors.

The following is an example of referencing the above pattern:

  1. . Modal {
  2. @ Extend % dialog;
  3. @ Extend % drop-shadow;
  4. @ Extend % statically-centered;
  5. /* Other modal styles */
  6. }
  7.  
  8. . Modal _ close {
  9. @ Extend % dialog _ close;
  10. /* Other close button styles */
  11. }
  12.  
  13. . Modal _ header {
  14. @ Extend % background-gradient;
  15. /* Other modal header styles */
  16. }

CSS lint

CSS Lint is a code Quality Check Tool written by Nicole Sullivan and Nicolas zakas to help CSS developers write better code. On their website, CSS Lint is introduced as follows:

CSS Lint is a tool used to help you identify problems in CSS code. It can perform basic syntax checks and use a set of Preset rules to check problems in the Code. The rules can be expanded.

CSS Lint is recommended:

  1. Do not show an ID in the selector.
  2. In multiple rules, do not use non-semantic (non-semantic) type selectors, such as Div and span.
  3. There must be no more than two Combinator in a selector.
  4. Do not start with "js-" for any class name.
  5. Warning should be given if layout and positioning are often used in non-"I-" prefix rules
  6. If a class is redefined as a subclass after definition, a warning should also be given.

Summary

CSS is not only a visual design, but also a best practice for programming. Rules such as Oop, dry, open/close, and content separation should be applied to CSS. No matter how you organize the code, make sure that the method actually helps you and makes your development easier and maintainable.

From: http://www.csdn.net/article/2012-11-30/2812325-CSS-Architecture

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.