Browsers can handle styling standard HTML web components, like <select> or <button>. They may vary in how they display these but they all have a default way which can then be overwritten with CSS. This is stored as a kind of internal CSS class in the browser and is easy to overwrite as it has almost zero specificity. Adding an element selector ‘select’, a class ‘.picker’ or an id ‘#picker’ will easily take control over the styling.
The problem arises when we create custom components that don’t have any default, zero specificity styling. Any styling that we do add when we design components has specificity so we immediately have a fight on our hands for which styling declaration gets control. We need some level of default styling, usually for layout as much as anything, to ensure that the browser cannot just show a mess of HTML elements.
Here are a few examples of how default component styling could be set and the problems associated with each approach.
Setting the CSS in an external stylesheet
We set the styling in its own CSS file. I’d say that this is the approach used by most UI tools like Bootstrap or jQuery UI. Various HTML elements in the component are given classes, which can be overwritten.
The problem is that they can only be overwritten by using higher specificity or by making sure that the overwriting style comes after the external CSS in the document’s source order. It also means an additional HTTP request to load a usually small amount of styling data.
Setting the style in a style attribute
We could add style attributes directly into the HTML tags. The problem here is obvious – super high specificity. This makes the styling very difficult to overwrite. You’re pretty much forced into using ‘!important’ declarations in your CSS, which not only feels wrong but really leaves you with nowhere to go.
It goes against the separation of concerns – content and styling but as this is intended to be default styling, which we would hope to overwrite, I’m not sure this matters.
Setting the style in a HTML <style> tag
We could place a block of HTML with <style> tags directly before or after the component HTML so that it effectively ships together. Placing <style> tags in the <body> was invalid in HTML4 but, if I’ve understood it correctly, can be used in HTML5 by using the scoped attribute, e.g. <style type=”text/css” scoped></style>. Browser support for this to be properly valid is not great at the time of writing (early 2016) – we get warning messages in consoles or code editors – but it seems to display as intended.
The problem with this approach is that the style is declared in the <body> whereas the overwriting CSS is probably declared in the <head> and so will not overwrite it without upping the specificity.