Creating proper selectors
The main problem of the CSS coder is creating proper selectors. Knowledge about priors in selectors is mandatory. It will help you to omit the !important
statement in your code and will help you to create smaller and more readable files.
Using IDs
Using of IDs in CSS is rather bad behavior. The foundation of HTML says that an ID is unique and should be used only once in an HTML code. It is good to omit IDs in CSS and use them only when it is the only way to style some element:
#id_name { property: value; }
Usage of IDs in CSS code is bad behavior because selectors based on ID are stronger than selectors based on classes. This is confusing in legacy code when you see that some part of the code is still preceded by another selector because it is added in the ID's parents-based selector as follows:
#someID .class { /* your code */ }
It is good to omit this problem in your projects. First, think twice if a selector based on an ID is a good idea in this place and if this cannot be replaced with any other "weaker" selector.
Using classes
Classes are the best friends of the HTML/CSS coder. They are reusable elements that you can define and then reuse as much as you want in your HTML code, for example:
.class_name { property: value; }
Grouping selectors
You can group and nest selectors. First, let's nest them:
.class_wrapper .class_nested { property: value; }
Then let's group them:
.class_wrapper_one, .class_wrapper_two { property: value; }
Interesting selectors
In CSS code, you need to be a selector specialist. It is a very important skill to make a right selector that will match a specific element in the DOM structure. Let's provide a little bit of fundamental knowledge about selectors.
Adjacent sibling combinatory +
The plus sign in CSS can be used in selectors in which you will need to select an element right after the element on the left side of the plus sign, for example:
p + a { property: value; }
This selector will return a
, which is right after the p
selector, like in the following example:
<p>Text</p> <a>Text</a>
But it won't work in the following case:
<p>Text</p> <h1>Text</h1> <a>Text</a>
Child combinator ">"
With element (>
) in the selector, you can match every element that is right into the element. Let's analyze the following example:
p >a { property: value; }
This selector will return all <a>
elements which are into<p>
element but are not nested deeper, for example:
<p> <a>text</a> </p>
But this won't work in the following case:
<p> <span> <a>text</a> </span> </p>
Adjacent sibling combinatory ~
With ~,
you can create a selector that will match every element that is parallel in the DOM structure, for example:
p ~ a { color: pink; }
This selector will work in the following cases:
<p></p> <a></a>
and:
<p>Text</p> <span>Text</span> <a>Text</a>
Getting elements by attributes
Sometimes, there is no way to create a selector based on elements, classes, and IDs. So this is the moment when you need to search for any other possibility to create the right selector. It is possible to get elements by their attributes (data
, href
, and so on):
[attribute] { property: value; }
It will return the following:
<p attribute>text</p>
And will also return the following:
<p attribute="1">text</p>
Attributes with exact value [attribute="value"]
In real CSS/HTML code, there are examples when you will need a selector which is based on attributes with an exact value like inputs with the type as text or when elements data attribute is set with some value. It is possible with a selector which is similar to this example code:
input[type="text"] { background: #0000ff; }
will match:
<input type="text">
Attributes which begin with [attribute^="value"]
This selector is very useful when you want to match elements with attributes that begin with some specific string. Let's check an example:
<div class="container"> <div class="grid-1of4">Grid 2</div> <div class="grid-1of2">Grid 1</div> <div class="grid-1of4">Grid 3</div> </div>
SASS code:
.grid-1of2 width: 50% background: blue .grid-1of4 width: 25% background: green [class^="grid"] float: left
Compiled CSS:
.grid-1of2 { width: 50%; background: blue; } .grid-1of4 { width: 25%; background: green; } [class^="grid"] { float: left; }
Let's analyze this fragment in SASS code:
[class^="grid"] float: left
This selector will match every element that has an attribute with a grid
word in the beginning of this attribute. This will match in our case: .grid-1of2
and .grid-1of4
. Of course, we could do it with SASS:
.grid-1of2, .grid-1of4 float: left
And get it in compiled code:
.grid-1of2, .grid-1of4 { float: left; }
But let's imagine that we have about 10
or maybe 40
classes like the following:
.grid-2of4 width: 50% .grid-3of4 width: 75% .grid-1of5 width: 20% .grid-2of5 width: 40% .grid-3of5 width: 60% .grid-4of5 width: 80%
In compiled CSS:
.grid-2of4 { width: 50%; } .grid-3of4 { width: 75%; } .grid-1of5 { width: 20%; } .grid-2of5 { width: 40%; } .grid-3of5 { width: 60%; } .grid-4of5 { width: 80%; }
And now we want to apply a float: left
to these elements like:
.grid-1of2, .grid-1of4, .grid-2of4, .grid-3of4, .grid-1of5, .grid-2of5, .grid-3of5, .grid-4of5 float: left
In CSS:
.grid-1of2, .grid-1of4, .grid-2of4, .grid-3of4, .grid-1of5, .grid-2of5, .grid-3of5, .grid-4of5 { float: left; }
It is easier to use a selector based on [attribute^="value"]
and match all of the elements with a class which starts with a grid string:
[class^="grid"] float: left
Whitespace separated attribute values [attribute~="value"]
With this selector you can match all elements which in list of "attributes" that contains a string described as a "value". Let's analyze the following example.
HTML:
<div class="container"> <div data-style="green font10">Element green font10</div> <div data-style="black font24">Element black font24</div> <div data-style="blue font17">Element blue font17</div> </div>
Now in SASS:
[data-style~="green"] color: green [data-style~="black"] color: black [data-style~="blue"] color: blue [data-style~="font10"] font: size: 10px [data-style~="font17"] font: size: 17px [data-style~="font24"] font: size: 24px
Compiled CSS:
[data-style~="green"] { color: green; } [data-style~="black"] { color: black; } [data-style~="blue"] { color: blue; } [data-style~="font10"] { font-size: 10px; } [data-style~="font17"] { font-size: 17px; } [data-style~="font24"] { font-size: 24px; }
And the effect in the browser is as follows:
Attribute values ending with [attribute$="value"]
In one of the previous sections, we had an example of a selector based on beginning of an attribute. But what if we need an attribute ending? With this feature comes a selector based on a pattern [attribute$="value"]
. Let's check the following example code:
<div class="container"> <a href="/contact-form">Contact form</a><br> <a href="/contact">Contact page</a><br> <a href="/recommendation-form">Recommendation form</a> </div>
SASS:
[href$="form"] color: yellowgreen font: weight: bold
Compiled CSS:
[href$="form"] { color: yellowgreen; font-weight: bold; }
The effect in the browser is as follows:
With the selector [href$="form"],
we matched all elements whose attribute href
ends with the string form
.
Attributes containing strings [attribute*="value"]
With this selector, you can match every element that contains a string in a value in any place. Let's analyze the following example code.
HTML:
<div class="container"> <a href="/contact-form">Contact form</a><br> <a href="/form-contact">Contact form</a><br> <a href="/rocommendation-form">Recommendation form</a><br> <a href="/rocommendation-and-contact-form">Recommendation and contact form</a> </div>
SASS:
[href*="contact"] color: yellowgreen font: weight: bold
Compiled CSS:
[href*="contact"] { color: yellowgreen; font-weight: bold; }
In the browser we will see:
With the selector [href*="contact"]
, we matched every element that contains the contact
string in the value of the attribute href
.
Using !important in CSS
Hah… the magic word in CSS, which you can see in some special cases. With !important
, you can even overwrite inline code added by JavaScript in your HTML.
How to use it? It is very simple:
element { property: value !important; }
Remember to use it properly and in cases where you really need it. Don't overuse it in your code because it can have a big impact in the future, especially in cases when somebody will read your code and will try to debug it.