Back to basic with HTML and CSS
Nowadays, many webpages are being styled using some kind of preprocessor (like SASS or LESS). This is also the case for HTML, which is usually generated by a CMS or web framework. All these abstractions make us think less about the basics of HTML and CSS and even worse, often result in bad quality code.
I decided to write down some of what I think are best practices (that can be used with or without advanced toolchains) which can make your basic frontend code better.
Start with writing HTML
When you need to build a page, try to understand the content of the page and then try to convert this to a semantic HTML structure. HTML5 comes with awesome descriptive tags like <article> and <section> which you can use to write down the structure and content of the design. Don't start adding CSS until the initial template is finished.
Don’t alter HTML to fit your CSS
When certain styles need to be applied to a template, it's often tempting to add a little <div> tag that can hold some of the styling. The problem with this is that you create a dependency between the HTML template and the CSS file. In other words: the template becomes more difficult to reuse. Other disadvantages are more complex DOM structures (performance loss) and HTML trees that are more difficult to read.
CSS is a very powerful language, it can usually do without adding extra tags. If the available HTML block does not offer enough flexibility, you can always try to use :before or :after pseudo selectors which allow you add 2 more layers to the element.
Select your elements using class selectors
When working with CSS, try to limit the selectors to classes only. It's perfectly fine to filter out a subset using something like nth-child(even) (for instance, when creating striped tables) but consider id and tag selectors a no-go.
Matching id's breaks reusability
Id's are unique, this means they give trouble when the same block is repeated multiple times. And we do wan't to be able to reuse our code, even on the same page. Therefore: don't rely on id's.
Matching tags breaks flexibility
Matching specific tags may seem useful (especially for typography) but also causes issues when refactoring code and changing the used tags. If your'e styling an <h2> element and suddenly someone walks in and asks you to change it to an <h3> for SEO reasons, the design will change as well.
Therefore, try to limit the use of tag selectors. There are of course exceptions, for instance when styling generated content from a WYSIWYG editor (we can't expect the end use to set the correct classes).
Don’t describe style in classes, describe components
Now that we've learned to use classes for everything, wee need to come up with some good descriptive names for them. Try to avoid describing the way it looks (e.g. alert--red), use something more descriptive instead (e.g. alert--danger).
The reason for this is that role of the HTML file is to describe the content, not the style. The CSS file is used to translate that content to a presentation with a certain look and feel. If someone decides at some point that red is to scary for people and it should be orange instead, you don't want to be stuck with alert--red.
Use a CSS methodology
Using a structured CSS methodology makes your project structure more predictable. This is especially useful when your'e not the only one involved in a project. There multiple CSS methodologies and if If you haven't decided on one yet, try out BEM.
Separate HTML templates according to your CSS methodology
Most CSS methodologies will focus on building some kind of reusable components. This is great, but only useful if the HTML part is reusable as well. If possible, use separate template files in the same structure as your CSS files. This makes it really easy to associate a stylesheet with a piece of HTML.
Scope! Don’t do anything outside the border box
I noticed that when building complex pages with multiple predefined/pre-styled components. Many times issues start to occur because the required margin of one component interferes with the space required by another component.
I decided that a component must not style anything outside it's outer border box. This means that any component should not set a margin on itself. It can however set a margin on it’s children. This way a block will have a predictable size and will not push other components away. This can be seen as a CSS version of React's one way data flow.