Book Image

Professional CSS3

By : Piotr Sikora
Book Image

Professional CSS3

By: Piotr Sikora

Overview of this book

CSS is the preferred technology to design modern web pages. Although CSS is often perceived as a simple language, applying modern styles to web pages with CSS and maintaining the code for larger websites can be quite tricky. We will take you right from understanding CSS to designing high-quality web pages in CSS3. We'll quickly take you through CSS3's features, and show you how to resolve common issues so you can build your basic framework. Finally, you will learn about code architecture and CSS methodologies used in scalable apps and you'll explore the various new features of CSS3, such as FlexBox, to help you create the most modern layout methodologies. By the end of the book, you will be a master at creating pure CSS web pages and will know sophisticated web design techniques, giving you an edge over other web designers.
Table of Contents (16 chapters)
15
Index

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:

Whitespace separated attribute values [attribute~="value"]

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:

Attribute values ending with [attribute$="value"]

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:

Attributes containing strings [attribute*="value"]

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.