Learn Web Development for Beginners: Styling Your Page With CSS
Previously we covered the basics of CSS: what it is and how to use them on our web page. Now, let’s talk about common CSS selectors and properties to learn more about what we can do with it.
CSS Selectors
We have learned how to apply CSS to our page and changed some colors to our HTML elements.
We have learned that we can apply the same styles to all elements of the same type with embedded and external styles.
We have also learned that styling a specific element can be achieved with inline styles. But what if we only want to target a number of tagged elements for styling?
In our page for example, if we have a hundred <p> tags on it, how do we change ten specific <p> tags without repeating the CSS code? We can’t rely on inline styles since it will force us to repeat the code.
That is where HTML attributes like the class=”” attribute comes in.
Let’s clear up our style.css file so we start with a page with no styles applied.
<h1>Welcome to My Website</h1>
<p>Hello, World!</p>
<p>From my first web page!</p>
<p>John Doe<br />- CEO. <a href="https://en.wikipedia.org/wiki/Seven_(1995_film)">Se7en</a></p>
<h2>Likes</h2>
<p>John likes Bread and butter.</p>
<p>He also likes Photography.</p>
<h2>Dislikes</h2>
<p>He doesn't like his socks to get wet.</p>
<p>He hates flying cockroaches.</p>
I made some adjustments to my index.html file to separate the likes and dislikes section.
Targeting the class
If we decided to make all the paragraph tags under the “Likes” section green, and all under “Dislikes” orange, we add a class to the tags:
<h2>Likes</h2>
<p class="text-green">John likes Bread and butter.</p>
<p class="text-green">He also likes Photography.</p>
<h2>Dislikes</h2>
<p class="color-orange">He doesn't like his socks to get wet.</p>
<p class="color-orange">He hates flying cockroaches.</p>
Then we add the following code to our CSS file:
.text-green {
color: green;
}
.color-orange {
color: orange;
}
The code above as expected will only target the elements with the matching classes.
The syntax for targeting a class is .class-name with a dot symbol (#) before the class name.
Targeting the id
We use the hash symbol (#) before the identifier name to target an element with an id=”” attribute like #section-title.
<h2 id="section-title">Likes</h2>
<p class="text-green">John likes Bread and butter.</p>
<p class="text-green">He also likes Photography.</p>
<h2 id="section-title">Dislikes</h2>
<p class="color-orange">He doesn't like his socks to get wet.</p>
<p class="color-orange">He hates flying cockroaches.</p>
#section-title {
color: blue;
}

Similar to the class attribute, if we have multiple elements with the same identifier, it will apply the style to all of them. CSS-wise, the code above works, but the usage of the id attribute is WRONG.
According to the W3 spec, an id attribute should be unique throughout the page. We used the same section-title identifier on two <h2> elements which isn’t allowed, but CSS couldn’t care less, it still applies the style to both of them.
To keep this guide from wandering outside CSS, we will not be covering how the id attribute works, just keep in mind that an identifier must be unique throughout your HTML page. If you’re planning to select multiple elements, stick with the class attribute and leave the id attribute for special cases.
Other CSS Selectors
Targeting the class and id attributes are so common that they use a special character to easily select them, but we are not limited to dots and hashes.
There are a lot of CSS selectors for special use-cases but is outside the scope of this guide. We will encounter some of them later, but to show you a bit of its power, check the following example:
<ul class="my-list">
<li>List Item 1</li>
<li>List Item 2</li>
<li>List Item 3</li>
<li>List Item 4</li>
<li>List Item 5</li>
</ul>
If we plan to style the last item on the list, we ought to add a class to the last element and add the corresponding style.
<ul class="my-list">
<li>List Item 1</li>
<li>List Item 2</li>
<li>List Item 3</li>
<li>List Item 4</li>
<li class="target-item">List Item 5</li>
</ul>
.target-item {
font-weight: bold;
}
If we add more items at the end of the list, we would have to update the class on the elements, and this goes on and on every time we update the list.
What if we don’t have access to the HTML page, or worse, we are tasked to style a page that is dynamically generated from a database?
Two words, pseudo-elements:
<ul class="my-list">
<li>List Item 1</li>
<li>List Item 2</li>
<li>List Item 3</li>
<li>List Item 4</li>
<li>List Item 5</li>
</ul>
.my-list li:last-child {
font-weight: bold;
}
The CSS code means: Select the last <li> element using the :last-child pseudo-element selector from .my-list.
Here are more pseudo-elements for a list:
- :first-child – Select the first child.
- :nth-child(3) – Select the third child.
- :nth-child(odd) – Select the odd children.
- :nth-child(even) – Select the even children.
- :nth-child(3n) – Select every multiple of 3 children (3rd, 6th, 9th…).
- :nth-child(3n + 1) – Select every multiple of 3 children starting from the first (1st, 4th, 7th…).

This is just the tip of the iceberg and there’s more to learn, but let us not get ahead of ourselves. I promise we will encounter more later in advanced topics, but for now, let’s learn little-by-little to cover web development as a whole.
CSS Properties
We have only covered a few of the CSS properties on our examples above, and I’m not planning to list every single CSS property available in this guide since it is already well-documented elsewhere like MDN’s CSS Reference.
You already know the basic syntax of CSS properties, but to give you an overview of the properties and their values, let’s start from the most common ones.
Colors
You never talk about styles without talking about colors. To summarize, everything you see in an HTML document can be colored: text, background, borders, shadows, forms, you name it. Whatever property you’re trying to color, you can define it a number of ways. Let’s cover the most common ones:
- Keyword – black, white, green, and red are a just few examples. You can check out MDN’s CSS Named Colors for the full reference of available named-colors.
- RGB –
rgb(0, 0, 0)
,rgb(255, 255, 255)
,rgb(0, 255, 0)
, andrgb(255, 0, 0)
. The values are using a functional syntax. From left to right, we have R, G, and B, which ranges from 0 to 255. - Hexadecimal –
#000
,#FFFFFF
,#00FF00
, and#F00
. These are the same colors as our keyword and RGB examples above, like the RGB values, the hexadecimal syntax takes R, G, and B starting from the left, which ranges from 0 to F (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F). There are two syntax to watch out for: the short#{R}{G}{B}
and the long version#{RR}{GG}{BB}
.
Aside from the keyword syntax, we can add alpha values to our RGB and hexadecimal colors:
- RGBA –
rgba(0, 0, 0, 0.5)
. The alpha value for the rgba() color function ranges from 0.0 to 1.0, where 1.0 is the most opaque. - Hexadecimal with alpha channel –
#ff000088
which follows the#{RR}{GG}{BB}{AA}
or#{R}{G}{B}{A}
syntax.
Here are some examples:
.panel {
/* Sets the background color of an element. */
background-color: coral;
/* Sets the text color of an element and its children. */
color: #2e1d44;
/* Sets the border color of an element. */
border-color: rgb(54, 22, 4);
}
Text and Fonts
In addition to HTML’s text formatting tags, we can also control the appearance of our text via CSS. In fact, our browsers apply a default CSS style to some of the HTML tags. The browser applies a font weight of bold to the <strong> tags for example.
With CSS, we can do a lot than HTML tags can offer:
- Size:
font-size: 16px;
font-size: 2rem;
font-size: 80%;
. - Weight:
font-weight: bold;
font-weight: normal;
font-weight: 900;
. - Style:
font-style: italic;
font-style: normal;
. - Line height (leading):
line-height: 18px;
line-height: 1.5rem;
line-height: 1.65;
. - Letter spacing (tracking):
letter-spacing: 1px;
letter-spacing: -0.5px;
. - Decoration:
text-decoration: underline;
text-decoration: line-through;
. - Font:
font-family: Helvetica;
font-family: Helvetica, sans-serif;
.
These are the most common properties for changing your text and font’s appearance.
Setting the font family is a bit confusing at first look. Its basic syntax is font-family: {font name}, {fallback}, {fallback};
. Starting from left to right, if the left-most font is not available (either on your site or on your machine), it falls back to the next font family on the right. In our example, if Helvetica is not available, it falls back to sans-serif: the browser’s default sans-serif font.
.panel {
/* ... continued */
font-family: 'Helvetica', sans-serif;
font-size: 18px;
font-weight: 400;
/* The line height will be 165% of the font size. */
line-height: 1.65;
}
Size and Spacing
When working with CSS, you’ll be working a great deal with size and spacing. Setting an element’s max width, setting its left margin, changing its padding are just the few examples.
Before we go further, you may have noticed the values and units we have used on the text and font properties above. These are px, rem, and %.
- px – Pixel is an absolute length unit and refers to each pixel of your screen. There are other absolute length units available like cm and in but px is widely used when dealing with absolute sizing.
- rem – A relative length unit based on the root’s (browser) font size. This is commonly used for setting the font size to make readability accessible. You may be surprised that a lot of users set their browser’s default font size. Setting your <html> font size to an absolute value (16px for example) will overwrite their preference, that’s bad for user experience. There’s also em that is relative to the parent element’s font size, and vw and vh which is relative to the viewport’s (screen) width and height respectively.
- % – The percentage unit may seem obvious to you but where does it base its value on? A lot of users skip knowing how percentage works in CSS, which in turn leads to confusion as they start using it. The percentage value is relative to an element’s parent, if your element is inside a 1000px <div> element, setting its size to 50% will calculate to 500px.
Like with text and fonts, we can use the different length units to set our element’s size and spacing. Let’s create a simple HTML card to visually represent the properties we are going to use.
<div class="card">
<h3>This is my card</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Alias commodi culpa earum, eveniet illum, inventore obcaecati odio officia optio suscipit temporibus, veritatis? Ab earum enim et mollitia necessitatibus placeat voluptas!</p>
</div>
.card {
margin: 24px auto;
padding: 48px 16px 16px 24px;
width: 300px;
min-height: 100px;
/* Color to spice it up. */
background: lightsteelblue;
color: midnightblue;
}
.card h3 {
/* Removes heading top margin from card. */
margin-top: 0;
}

Note how I set the values for both margin and padding properties, it’s a shorthand version for setting the values around the element.
margin: 24px auto;
– The syntax is: {top-bottom} {left-right};
. Which means 24px for top and bottom, while auto for left and right margin.padding: 48px 16px 16px 24px;
– The syntax is: {top} {right} {bottom} {left};
. This sets the padding starting from the top, then moves clockwise.

Inline-level elements with padding
Setting a padding to an inline-level element may not behave like you would expect it to.
Given a line of text with a link wrapped inside a <p> tag, we wanted the link to look like a button so it would stand out.

With what we have learned, we normally add a background and a padding to the link to achieve the button appearance:
#unique-link {
padding: 24px 8px;
background: greenyellow;
}
Here’s what it looks like:

You would expect the text to wrap around the link instead of overlapping. The reason for this is that inline-level elements cannot have a width and a height value, it can take a padding and margin, but will only respect the left and right padding or margin.
Try it out for yourself: try adding a width, height, and margin to the link and see what happens.
Only block-based elements respect the sizing properties we set them.
We can set the link to a block-level element via CSS but it would take it’s own line and breaks the text block’s continuity.
#unique-link {
padding: 24px 8px;
background: greenyellow;
display: block;
}

As you may have noticed, since it’s now a block-level element, it would take 100% width and accounts the padding we set to it, but it is in its own line like block elements behave.
By default, HTML elements are only either block-based or inline-based, but with CSS, we can have both.
#unique-link {
padding: 24px 8px;
background: greenyellow;
display: inline-block;
}

display: inline-block solves the dilemma. It basically makes the element respect the sizing properties we give it, and at the same time sit within inline elements (like text).
Since it is also an inline-level element, setting a text alignment property on its parent will affect the inline-block element. This is how you center a button inside a container:

On the above screenshot, the middle button is in its own container.
<p class="narrow-p text-center">
<a href="#" id="unique-link-2">This is a centered link</a>
</p>
.narrow-p {
max-width: 300px;
}
.text-center {
text-align: center;
}
Set your link’s style to the following to make it a proper button:
#unique-link {
padding: 6px 10px;
background: greenyellow;
display: inline-block;
color: #000;
border-radius: 4px;
border: 2px solid #000;
text-decoration: none;
font-size: 14px;
font-weight: bold;
}
This section got longer than it needs to, but it’s better to understand how sizing works in CSS early on to avoid bugs and know how to fix them.
Layout
We have learned about manipulating colors, text, and sizing, but without the layout properties, we can only do one-column websites. Not that one-column websites are not good web design, but you can’t be a good web developer without mastering CSS layouts.
In CSS, layout properties give you the ability to change your elements’ position around the page. By default, HTML elements stack on top of each other, with CSS layouts, we can make two or more sections sit in one row for example.
Let’s look at some of the most common layout properties at a higher level for now, since going in detail is reserved for intermediate and advanced guides.
Position
- position: static; – The default position value for all HTML elements.
- position: fixed; – If you want to place an element at a location on the screen and keep it there even if you scroll around the page. Example: Annoying banner ads on shady websites 😉
- position: sticky; – Initially behaves like static, but behaves like fixed once you reach it when scrolling down. Example: sticky sidebar table of contents.
- position: relative; – Flags the element as relative, which works with position: absolute;
- position: absolute; – Positions an element relative to the nearest relative ancestor. By default all absolute elements are relative to the <html> element. Setting an absolute element’s top and left properties to -20px for example will create a negative offset, which places the element outside its relative ancestor’s bounding box. See an example below.
Except for position: static; setting an element’s position to any of the mentioned values can be controlled with the top, right, bottom, and left properties.
.box-1 {
position: relative;
width: 200px;
height: 200px;
background: #e5e5e5;
}
.box-2 {
position: absolute;
top: -20px;
left: -20px;
width: 100px;
height: 100px;
background: #7777ff;
}
.sticky-sidebar {
position: sticky;
top: 20px;
/* Offsets 20px from the top when the element starts to "stick". */
}
.fixed-ad {
position: fixed;
top: 32px;
right: 32px;
}
Display
We have learned about block, inline, and, inline-block display values before, but there’s more to it than just changing how an element behaves.
In the past, a lot of people were using display: table to create complex layouts, but it comes with a lot of bugs and is difficult to work with. Today, newer CSS technologies are available to make our lives easier, thanks to modern browsers (no thanks to you Internet Explorer).
- display: table; – If you wish to stay in the past.
- display: flex; – Turns an element to a flexbox, distributes all its children in one row by default where their width are automatically calculated. Flexbox comes with a number of properties to control its children’s layout which makes this one of the most powerful layout-ing tool.
- display: grid; – Like flexbox, this modern CSS technology is so powerful that you may no longer need a grid-system framework. With grid, you can set columns, rows, and gaps to a parent element, and the children will follow.
There are other display properties available but is not relevant to this guide.
Here are some examples with flexbox and grid.
.flexbox {
display: flex;
/* Sorts the children in reverse in a row. */
flex-flow: row-reverse;
/* Vertically aligns the children at the center. */
align-items: center;
/* Horizontally packs the children at the center. */
justify-content: center;
}
.grid {
display: grid;
/* Sets a 3-column grid with equal column widths. */
grid-template-columns: 1fr 1fr 1fr;
/* OR */
/* Sets a 2-column grid where the first column takes 80% of the space
while the second column takes 40% of the space. */
grid-template-columns: 8fr 4fr;
/* Sets a 24px gap between rows, and 40px gap between columns. */
gap: 24px 40px;
}

Float
If this is not the first beginner CSS guide you’ve read, you have probably encountered float used to create columns. Before flexbox and grid, Float was the standard when creating complex layouts. Today, it is still widely used, but I completely adapted to flexbox and grid for their stability, and only use floats to “float” elements around text blocks.
To use floats for layouts and avoid bugs, you have to use a utility class called clearfix.
<div class="clearfix">
<div class="col-1">
Column 1 content
</div>
<div class="col-2">
Column 2 content
</div>
</div>
.clearfix::after {
content: "";
clear: both;
display: table;
}
.col-1 {
float: left;
width: 80%;
padding-right: 40px;
}
.col-2 {
float: right;
width: 40%;
}
Although floats are still not obsolete, I would suggest using flexbox and grid early on to master it.
To learn more about CSS flexbox read CSS-Tricks’ A Complete Guide to Flexbox. To learn more about CSS grid read CSS-Trick’s A Complete Guide to Grid.
Summary
We have covered a lot for a beginner’s guide and I’m glad you made it through.
We covered what CSS is and how to apply it on our HTML pages. We have also touched the basics of how CSS works by covering CSS selectors and common CSS properties on a higher-level.
If you’re stuck or having problems with your code, don’t hesitate to comment or contact me, I’ll do my best to respond as quickly as possible.