3. CSS Basics
Cascading Style Sheet - that's what CSS means, which is the flesh of your HTML document (or, the dress it wears). Most of simple website projects could be done with HTML and CSS alone, just like this course website. Surprise!
Before we start... / Style sheet, understood. But "cascading"? / Global thinking, efficient execution / CSS syntax, a breakdown / Experimenting different styles / Fonts and colors / CSS Units / Page and text Layout / Aesthetics / Position / More on selector / Before the next unit...
Before we start...
Let's take a look at some English writing issues I found in your autobiography, so you can keep improving the quality in the future.Style sheet, understood. But "cascading"?
These are the relevant definitions of cascade as a verb from Oxford Learner's Dictionary:
to flow downwards in large amounts
to pass information, knowledge, etc. to a person or group so that they can pass it on to others; to be passed on in this way

Remember that in the Document Object Model (DOM), we can define the relationship between HTML elements. In a style sheet, when you specify the style of a parent/ancestor, the style would cascade down, flow downwards, or pass on to its children, until the flow encounters a different style (that is, you specify a different style for the children). Alternatively, we can say that the child inherits a style from its parent/ancestor.
In the following HTML document, for instance, if <html>
is specified to display texts in Times New Roman, it's child <div>
will also inherit this font style, unless you specify a different font type (e.g., Calibri) for it - the style flow is then stopped.
<body>
<div>
</div>
</body>
The above principle applies to many CSS properties, but with a bunch of exceptions, too (see the Inherited?
column on this page). For example, a font size would be reasonably inherited by default from a parent by its children, so you don't need to set the same font type over and over again. But a margin is not going to be automatically inherited from a parent, or every child element enclosed in the other element is going to be more distant from the edges of the parent, which is going to drive Web designers crazy. When we move on, you can come back and check this MDN Web Docs page for some more details.
The most updated CSS system is CSS3, although we would mostly use the features that are well-developed following W3C standards from early on. There are also many new stuff in CSS3 that can create some very fancy effects in your webpage. But again, be very careful when you try to use them because some might be too new to be supported in all major Web browsers. MDN Web Docs still provides you a very complete CSS guide that you should always refer to.
Global thinking, efficient execution
In the previous unit, I talked about how to organize the files in your website, which is part of the global thinking required for your Web development project. I told you that when you create a css directory in the root directory of a website project, it has the implication that the styles specified in the CSS files in this directory would apply to the entire website, presumably because, for instance, you have the same navigation pane in different webpages. You probably don't want to include styles that are specific to some elements in some specific webpages that belongs to a specific sub-project - these styles should go to a CSS file located in the css directory of the sub-project folder, which is only loaded when those specific webpages are presented in a Web browser.
Let me again use my course website as an example. In the file structure below, I have a bwd directory and a meteor directory right under the root directory because I have two course sub-projects. Under the root directory, I have a css directory for global CSS files, because I assume that my bwd and meteor would have a similar layout (for instance, the same style for the navigation pane) and I only need one CSS file for these common styles. But I also expect both projects to have some unique presentation of their contents, which requires some styles that are not useful for the other project, and I would put them into a CSS file in the css directory of each sub-project.
/ (root) | ─ index.html (default homepage) | |
┕ /css (global css files) | ||
┕ /analysis | ─ index.html (course default homepage) | |
┕ /css (analysis site css files) | ||
┕ /personal | ─ index.html | |
┕ /css (personal css files) |
Are these manipulations crucial?
Maybe, depending on the scale of your Web development project. It's not about the performance of your website, because modern computers are very powerful, and most of time you probably won't feel the difference in whether a website loads a tiny CSS file with only essential styles or a sizable one with lots of redundancies. Things could go wild very easily, however. The less planning you do, the more time you could waste on fixing problems.
CSS syntax, a breakdown
OK, enough life lessons. Let's first create a css directory inside your cv directory (because I'm assuming that your themetic website will look very distinct), and then create a style.css file in the css directory. The filename is not going to matter, but you always have to choose a sensible one - what could be more sensible to name the file style.css if the file is really just for styling...? (Let's agree to disagree). In the CSS file, the syntax of a given style should look like this:
selector {
property: value;
}
In the above style template, selector allows a Web browser to pin down a group of elements or one single specific element in a DOM. The curved brackets { }
defines the scope of a style, in which the value of properties of the style are specified. There are many CSS properties for you to change the visual representation of a webpage, such background color, font color, font style...just too many of them. We usually use one line for every single property which must ends with a semi-colon ;
, and in each line, the name of the property and its value must be separated by a colon :
. Did you happen to notice the indention at the beginning of a property line, and know why this is recommended? In addition, we can still add some notes that will not be considered part of styling for our own reference with the following line:
/* some notes in a CSS file! */
Let's try to create your very first style and apply it to your personal website. In your style.css for the personal website, add the following style so the background of <body>
will have a pink color.
body {
background-color: pink;
}
Now link the CSS file to index.html by adding the following line into <head></head>
so the default homepage would be styled based on the CSS file. Note that in our case, the path in this link does not begin with /
, because the CSS file is not located in a css directory under the root directory. Instead, the CSS file is located in the css directory in your analysis directory, along with the index.html file it styles. This type of paths is called relative path, because the path to the linked CSS file is relative to the HTML file.
<link rel="stylesheet" href="css/style.css">
If you've done everything correctly, you should see the fancy pink color in the background of the homepage of your personal website. And you would observe the cascading effect, too; every element inside <body>
has a pink backgroud. Let's try to stop this cascading effect by specifying a different background color for the children of <body>
...say, <section>
...? Add the following style to the style.css file, and you will see the contrast. Most of the elements inside <body>
still has a pink background, except for every single <section>
element (and it's children), which now has a white background.
section {
background-color: white;
}
The <style> element and inline styling
If you search for some information about CSS on the internet, you probably will see two alternative methods of styling the elements directly inside your HTML files. The first one is to define the styles directly inside the <style></style>
element, which is then inserted into <head></head>
as part of the metadata of a webpage, as in the following example:
<style>
body {
background-color: pink;
}
</style>
This would be useful when you have some styles that are only applicable to the elements in a webpage. But I personally wouldn't recommend it. If later you decide to extend these styles to other webpages, you still need to move them to a CSS file so you don't have to repeat these styles again and again in different HTML files.
Alternatively, you could put CSS properties in the value of the style attribute of an HTML element (namely, inline styling) to style that particular element, as in the following example:
<body style="background-color: pink;">
This technique would be useful if you need some special presentation for just one element, and you're pretty sure that you won't use it anywhere else. In this course website, I need to present some special examples from time to time, which requires some CSS styles just for these examples. This is the case where I choose to just use inline styling, because the styles are not going to be reused again. However, if you have lots of properties to specified even just for a single element, you'd better define this style in a CSS file since it would be easier to read in the source code. We will return to inline styling later in this unit.
In general, you can follow the tips below to decide where a style settles in:
- If a style applies to every single page in your website, put it inside
/css/style.css
and import it to every webpage. - If a style applies only to every single page in a sub-project in your website, put it inside
project/css/style.css
. - If a style applies only to one webpage, put the style in
<style></style>
of the HTML document. - If a style applies only one element of a webpage, use the
style
attribute of that element to specify the style.
Vendor prefix
This is just a side note, but one special thing about CSS property you need to pay attention to is called vendor prefix. Sometimes a CSS property is just introduced and being experimented, so different Web browsers have their own ways of applying these properties and you need to add the proper vendor prefix to get the expected CSS effects across different Web browsers (for instance, -webkit-transition
). Here is the list from this MDN Web Docs page:
-webkit-
- for Webkit-based browsers like Chrome, Safari, and iOS browsers-moz-
- for Mozilla Firefox-o-
- for older Opera-ms-
- for Internet Explorer and Microsoft Edge
Most of times you can just use the name of a property without and vendor prefix at all. But in case that you find anything wrong with a CSS property only in some specific Web browsers, then you might want to check if you need a vendor prefix for that CSS property.
Experimenting different styles
When you begin to style your webpages, you naturally keep adjusting the properties until you settle down on the layout that you're satisfied with. Normally, this means to constantly make changes to your CSS file in a text editor, upload it to your website, and check the changes in your Web browser. There is nevertheless a hidden tool in your Web browser that you can use to experiment and examine changes in real time, which is mostly called Developer Tools. Well, you may have come across it in your Web browser when you hit F12 by accident and didn't know what to do with it:

For a simple Web design project, there are two very useful sections in the Developer Tools. One is Elements, and the other is Console. Let's focus on Elements first, in which you will see the HTML elements and their structure in your webpage. When you click on an element, its style will appear in the Styles panel on the right. In the Styles panel, you can freely add new styles or adjust the existing ones, and the changes will apply to the current webpage accordingly.
Thus, with this tool, you could experiment some styling directly in your webpage first, and then make the same changes to your CSS file when you're contented. This will save you some time because you don't need to blindly change your CSS file repeatedly.
Fonts and colors
You don't just use the same font in a website, not only because your website could look boring, but also because texts in a webpage generally convey different messages - titles, headings, menu items, paragraphs...They all need be made distinct so readers know what they are looking at. In this course website, I use five different fonts: One for the (page) title using the first-level heading <h1>
, two for the second-level and third-level heading <h2>
and <h3>
respectively, one for the texts in full paragraphs, and one more for examples that mostly involve some source codes. Of course, you don't use too many fonts in your website either to avoid making reading impossible.
At the very beginning, I've already asked you to explore Google Fonts to see what kind of fonts you favor. Unsurprisingly, there are more fonts for English than for other languages, given the relatively small number of characters the developers need to create. For Traditional Chinese, we only have two choices Noto Sans TC and Noto Serif TC, but they are still way more pretty than the build-in Chinese fonts in some operating systems. Plus, it's free, so we cannot ask for more from Google.
In Google Fonts, you can click on a font you like, and select the font style you need. You can include all the fonts and their styles in a list at once. Then, in a panel on the right side of the webpage, you will see the Embed option as in the figure below, which provides two methods of introducing the selected fonts to your website.

The first method provides you a line of <link>
codes, which you can put into the <head>
element as part of the metadata of your website:
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300&display=swap" rel="stylesheet">
The second method provides you a line of @import
codes, which you can put into the first line of your global/local CSS file (it is in fact embedded inside the <style>
element which is supposed to be inserted into <head>
, but I already explained why this might not be the best idea):
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300&display=swap');
I personally always prefer the second method, since the font styles I choose are usually applied across all webpages. Since I already have to load the global/local CSS file for every webpage, why don't I just load the font styles from Google in my CSS file, so I don't have to repeat the <link>
codes in the metadata of every webpage.
How do you choose fonts?
Hmm, good question. I'm no typographer, so I generally follow the rule of thumb and then pick the fonts I feel appropriate (so I could be wrong, and you need to dig deeper by yourself). All fonts could be categorized as either Serif or Sans-serif. The former type has small strokes attached to the end of main strokes (as in the fonts you're seeing now in this website), which give the characters more details. It is believed that serif fonts are easier to read than sans-serif fonts, especially in print, which is also the reason that they are commonly applied to body texts. Sans-serif fonts, without those extended small strokes, usually have square or round edges at the end of a stroke. They are usually used for large-size texts such as headings, rather than for body texts.
So, if you want to play safe, just follow the above rules, and the texts in your website should look just fine. Whenever you need to choose multiple serif or sans-serif fonts, you probably don't want to pick those that look very different, because you want some visual consistency in your website, too. Of course, bold combinations could have some unexpected positive effects, but I'm not the one to guide you. Here's a webpage showing some popular combinations of fonts provided by Google.
After you make your decision and embedded the essential codes into your website to load the fonts, you should also add some notes to your CSS file to remind yourself which font is for which part of texts in your website, just like what I do for mine, too:
/*
Main Title/h1: Mukta
h2: Dosis
h3: Thasadith
body: Zilla Slab
code: Lekton
*/
When you need to apply a font style to an element, add the font-family
property to the style you defined in your CSS file, just like:
font-family: Zilla Slab, serif;
In this property, you can specify more than one fonts separated using a comma. A Web browser will try to apply the first font style, and if the first style is not available, it will try the second one, and so on, until it finds an available font style. In the above example, I added serif as the last resort, so a Web browser to use whatever serif font available to it when there's no other available choice. You should instead add sans-serif at the end if other specified fonts in the same line are also sans-serif, so some consistencies could be maintained, although the replacement would not give the best look of your website.
Now, take some time to get the font part done. You can surely change your mind later, but your initial attempt might not be bad at all!
A colorful world
There are more decisions to make, and this time it's about the colors in your website. Colors undoubtedly have their visual/emotional impacts, you need to choose them wisely. Again, I'm not expert, but the keywords for you to google would be psychology of colors. For this course website, I just followed my instinct to use the combination of red, organge, green, and black colors. Red and organge stand out because I use them to put an emphasis on various elements, so they become the theme of my website - McDonald's uses this color combination, too, so don't judge!
You don't use colors just to make your website look fancier than others. Colors are just like fonts, which would help convey systematic messages of your website:
- The theme of a webpage.
- The highlights in a webpage.
- Distinct sections in a webpage.
- Etc.
In CSS, you can specify a color in many different ways. One is to use the word that represents a color, such as black, red, and pink, which we have tried earlier (see this W3 Org page for all the color terms you can use directly). There's no much flexibility with this method since the subtly difference in colors cannot be specified using words in CSS. Alternatively, most Web designers would choose to use RGB value or HEX code to specify a color:
background-color: rgb(0, 0, 0); /* both represents a black color */
background-color: #000000;
I've never received any professional training in digital art, so I choose to use the HEX system only because it's easier to type. You can make your own choice based on what you know (or like) for sure. OK, let's set the tone for your website, and don't forget to add some note in your CSS file to remind you the function of each color of your choice, such as:
/*
text color: #383838; (light grey)
link color: #cccccc; (super-light grey)
link hovered color: #000000; (black)
menu bg color: #b30000; (dark red)
section bg color: #f2f2f2; (lighter grey)
highlight color: #e68a00; (dark orange)
code color:#226d6d; (cyan)
*/
CSS Units
You must have been waiting for a tutorial for how to adjust the size of texts and elements in your website, and there you go! There are different units in a CSS file that you can use to define the size, distance, width, height, etc., and we'll start with absolute length units (from W3CSchool). They are absolute because the units refer to an absolute scale and are not dependent of other specified lengths in an HTML document. Among the units in the following list, px is probably the most frequently used absolute length unit in Web design - the screen resolution is defined by pixels and the dimension of an image is commonly specified with pixel, too. When we learn to use JavaScript to retrieve the dimension of an element, you get pixel as the measure by default. Again, I could be wrong, but when referring to pixel, I also feel more comfortable with estimating the size of an element in an webpage across different devices.
cm
- centimetersmm
- millimetersin
- inches (1in = 96px = 2.54cm)px
- pixels (1px = 1/96th of 1in)pt
- points (1pt = 1/72 of 1in)pc
- picas (1pc = 12pt = 1/6 of 1in)
Many things could be either absolute or relative, just like the path to a file that we have discussed previously, so it's natural that we have relative length units as in the following list, too. When you use a relative length unit, the actual length is relative to some other length. For instance, if the font size of a <div>
element is set to 16px
, and you want emphasized texts in the element are twice larger, then you could set the font size of the emphasized texts to 2em
.Well, you could simply use 32px
, too, but soon you will find this strategy very inefficient because every time you change the base font size, you need to change all associated font sizes. systematic messages of your website.
em
- multiplying the font size of the current elementrem
- multiplying the font size of the root elementvw
- relative to 1% of the viewport (the browser window size) widthvh
- relative to 1% of the viewport heightvmin
- relative to 1% of the smaller viewport dimensionvmax
- relative to 1% of the larger viewport dimension%
- relative to the parent element
My own strategy is even more radical. In some cases, I even start with the relative length unit as the base to make sure that the webpage is in general consistent across different devices. For instance, I might set the base font size to 1.5vh
, that is 1.5% of the browser window height, so whether the screen width is 1920px, 768px, or 1280px, the font size is proportionally the same on a webpage. Why vh, rather than vw, then? Because the length of a font in fact determines the height of the font, and its width is calculated automatically. With the baseline, the size of emphasized texts could be set to 2em
, which is equivalent to 3vh
. This strategy is also the foundation of Responsive Web Design, which focuses on providing a unified browsing experience for your website. We will be back to this a few weeks later.
One final thing about length unit is the complication that stems from the border of an element. It is common an element is decorated with borders for its edge to be visible, but now you need to choose if the calculation of height/width of the element includes the borders or not. If not, you choose to measure/define height/width with a content-box, which gives you the dimention of the red area in the block below. Alternatively, you could choose to measure/define the dimension of a border-box, which takes borders (the blue edges in below) into consideration.
CSS Pixel Ratio
Regardless of whether you use an absolute unit or a relative unit, the font size should not always be estimated using the physical screen resolution of a device. For example, with a screen resolution of 1920 x 1200 pixels, if you set font-size
to be 16px, you would think that each character is as tall as 16 / 1200 = 1.33% of the screen height. This is almost always true for a laptop or desktop computer. For mobile devices, however, things would be different due to CSS pixel ratio. Modern mobile devices usually have a high-definition physical screen resolution, such as 1125 x 2436 pixels for iPhone XS. If you still have the same font size of 16px, each character would be just like an atom on its screen. So, to avoid damaging our eyes, software engineers have decided to set a different resolution specifically for Web design through a CSS pixel ratio. For iPhone XS, the ratio is 3:1, which means that the resolution that will be processed by a Web browser in iPhone XS would be 1125/3 x 2436/3 = 375 x 812 pixels. This way, everything will be presented in a more reasonable size in a mobile browser. When it comes to Responsive Web Design, you always need to check the CSS pixel ratio to know how to set the size of individual components in your website.
Border-box or content-box?
It might be more logical to adopt border-box as a default, since normally you wouldn't evaluate the dimension of an element by excluding its borders. For instance, when you want to clear an area on your wall to hang a beautful framed picture, you wouldn't just think about the dimension of the picture itself, but also the borders created with the frame, right? This would be mostly irrelevant because not many elements need borders, and the edge of an element could be made distinct in many different ways (by setting a background color, for example). But for now, let's make border-box as the default for all elements in your webpage by setting following style in your CSS file (the selector *
is a wild card character that means any character, which thus selects every elements): systematic messages of your website. And since this style applies to all webpage, you know where to put this, right? It should be placed inside /css/style.css
.
* {
box-sizing: border-box;
}
Page and text layout
Now you have the knowledge to quickly fine-tune the layout of your webpage, and let's us start with margin and padding. Margin specifies the space between elements, both vertically and horizontally. Padding defines the space between contents and borders, both vertically and horizontally. You can define the spacing toward a specific direction (top, right, bottom, and left), using the properties such as margin-left
or padding-bottom
:
left element | margin-left | target element |
padding-bottom |
Alternatively, you can define the spacing in general using the property margin
and padding
. Depending on the number of values you specify for these two properties, the spacing is set clockwise around or within an element: systematic messages of your website.
margin: 0; /* zero margin on all four sides */
margin: 0 0 0 0; /* as above */
margin: 1px 2px 3px 4px; /* 1/2/3/4px for top/right/bottom/left respectively */
margin: 0 2px; /* zero for top/bottom, 2px for left/right */
margin: 0 2px 5px; /* zero for top, 2px for left/right, 5px for bottom */
The above logic applies to all CSS properties that refers to the four sides of an element, such as border
.
Resetting margins and paddings
Different Web browsers have their default margins and paddings for some elements, so to provide a unified layout across the browsers, we need to reset margins and paddings with the following style in your CSS file, namely to set zero margins and paddings for all elements. Again, you should always do this for your every single webpage, so it should go to /css/style.css
:
* {
box-sizing: border-box; /* from the old style */
margin: 0;
padding: 0;
}
Margin Collapsing
Before we end the current tutorial about margin and padding, there's something you should know when you set the margin for adjacent elements, that is, margin collapsing. For instance, when you define the following style in your CSS file, you might hope to a <div>
element from its previous and following elements (as well as the top and the bottom edge of a webpage) by 15px.
div {
margin: 15px 0;
}
But if this style applies to two adjacent <div>
elements without any adjustment, the two elements are supposed to be separated by 15px (margin-bottom of the first) + 15px (marigin-top of the second) = 30px. This is not what you hope for, and the Web browser simply collapses these margins for you and make it just 15px. This strategy of presenting your webpage makes sense because you don't need extra spacing with additive margins.
You might have already thought of some workaround, such as using margin-top
to separate elements by top margin, but in this case you would have to specify the bottom margin for the last element of a webpage. So, why not just give in and take full advantage of your Web browser's ability to read your mind? :-) There many different conditions where margin collapsing does or does not apply. See the MDN Web docs page for more details. It is a rather minor issue, but you might want to master it to always get the expected layout right.
Typesetting
OH MY GOD. How long did it take us to here? Your favorable fonts are waiting, and you must be wondering when we will put them to use. Previously, we talked about font-family
, which allows you to set the specific font type for an element, but there's a whole family about font style in CSS:
font-family
- see previous section for explanationsfont-style
- normal/italicfont-weight
- bold/bolder/(specific font weight)font-variant
- small-capsfont-size
- define font size with length unitsline-height
- define line spacing with length units
You could also use the shorthand font
by specifying the above properties in the order (style)-(variant)-(weight)-(size/line-height)-family. In the first example below, the font
property set an italic, non-small-caps, and bold font with a size of 20px and a line height of 30px using Zilla Slab or any serif font. In the second example, the font size is set to 10px, and the font family is set to sans-serif; other values that are omitted are set to default.
font: italic normal bold 20px/30px Zilla Slab, serif;
font: 10px sans-serif;
With the above in mind, we can start to set the font style for the entire webpage, by adding the font
property to the style of <body>
to your CSS file, just like the example below.
body {
font: 1.6vw/2.4vw Zilla Slab, serif;
}
Note two things here. First, I adopt the more radical approach by using the relative length unit for my font size and line height, because I want the two properties to adapt to different screen resolutions. Second, the values assigned to the font
property here are for the body texts; the font size is appropriate for large amount of texts, and the font type is a serif font. This makes sense because we are styling <body>
, rather than other elements, and everything we do has to be semantically meaningful. Also note that I prefer to set the line height to be 150% of the font size in an element, which in general makes texts easier to read. You can also define the font color for body texts using the property color
and assign an RGB or HEX value to it. systematic messages of your website. Since you already have a root element, which is <body>
, you can use another relative length unit for the font size and line height. Do you still remember which one it is? (select the following blank section to find out!)
h1 {
font: 2rem/3rem Mutka, sans-serif; /* rem = relative to the root element */
}
We can also set margins and paddings for our containers, such as <article>
, <section>
, and <p>
. In this course website, every webpage is viewed as an article, and I prefer to have some small space between its contents and the four edges, thus the padding
setting below:
article {
padding: 0.5vh 1vw; /* 0.5vh padding from top/bottom and 1vw padding from left/right */
}
Then, both <section>
and <p>
are used by me to represent a paragraph in this course website, so I add some margins for them to slightly separate them from each other vertically. Note how it is possible to have more than one selector in your CSS file - just separate them with a comma:
section, p {
margin: 0.5vh 0; /* 0.5vh top/bottom margin */
}
You can try many different margins and paddings for various elements until you're satisfied with the visual presentation of the overall layout.
Aesthetics
You might be eager to try other things to beautify your webpage, and here are some more tips for you. There are just too many of them, so it's not possible for me to answer all How do you... questions. But I'm pretty sure that once you feed Google with your questions, you will find the answers pretty soon. For example, if you google How to animate background color in CSS?
, you will see many solutions.
Body
The first thing we would do here is to further style the <html>
with the width
and height
properties and set their value to 100%
, so the entire HTML document takes up the entire viewport (as the browser window is the parent of <html>
) by default.
html {
height: 100%;
width: 100%;
}
Then we set <body>
element to have min-height
and width
as 100%
. We choose to set min-height
instead of height
because not only do we need <body>
to inherit the full window height from its parent - <html>
, but we also need to allow <body>
to expand its height when the contents of the webpage grows longer than the viewport height. Next, we add the overflow-x
property and set it to hidden
so the horizontal scroll bar does not appear. This will guarantee the display of your webpage to only take up the full width of the browser window. We also add and set the overflow-y
property to auto
, so the vertical scroll bar appears when the height of a webpage exceeds the height of a browser window. It's always easier to both read and scroll from top to bottom than from left to right (or right to left).
body {
min-height: 100%;
width: 100%;
overflow-x: hidden;
overflow-y: auto;
font: 1.6vw/2.4vw Zilla Slab, serif;
}
Hyperlink
Most Web designer would also choose to style hyperlinks marked up by <a>
since the default style in a Web browser doesn't look decent. Hyperlinks usually are underlined by default, but you can change this by set the text-decoration
property to none (or you can play with the property to adopt different kinds of text decoration). But you still need to make hyperlinks distinct from other normal texts, so you probably want to use a different font color for <a>
. You can further differentiate hyperlinks by making them bold. Again, try many different things, and find the style you prefer.
a {
color: grey;
text-decoration: none;
font-weight: bold;
}
Border
As mentioned earlier, one way of making the edges of an element apparent is to style its border
. Just like margin
and padding
, you can choose to style one of the four borders (with border-left
, for instance), or use the shorthand border
to style the four borders altogether. In each border
property, the values are specified in the order width-style-color as in the following example (see this W3CSchool page for different border styles that you can play with):
border: 2px solid red;
Border radius
You might not just want a rectangular with right angles, and that's when the border-radius
property is useful. In the following example, the value 3px
means to align a circle with a diameter of 3px to each of the four corner of a square, and cut the corner edge following the edge of the circle, thus the round edges. As usual, it's possible to set each of the four corners separately, starting with the top-left corner. I'll just leave it to you.
border-radius: 5px;
Shadow
I sometimes like to add shadows to make some elements fancier (for instance, headings), although not in this website. The properties text-shadow
and box-shadow
could be used to decorate texts inside an element and an element itself respectively with some shadows. The two first values control the direction of the shadow (positive value = toward the right/bottom; negative value = toward the left/top). The third value control the blurriness of the shadow, and the last value determines the color of the shadow:
text-shadow: 0.3vh 0.3vw 0.2vw grey;
box-shadow: 1vh 1vw 0.2vw red;
There are just too many tricks you can do to make your website pretty - just google your ideas!
Position

You really, really, really want to juggle things around, so you need to know how to position elements in a webpage, with the position
CSS property, of course. There are four common position settings in CSS:
static
- the default positionrelative
- relative to the original (static) positionfixed
- fixed to a given position relative to the viewport (browser window)absolute
- relative to a positioned parent/ancestor, or<body>
if there's no such element.
Except for the default position static
, other positions could be defined along with the CSS properties top
, right
, bottom
, and left
. We will play around these properties in this section.
Relative
Remember that with the default position, elements are presented from top to bottom (block elements) and left to right (inline elements) following their order in an HTML document. When you set the position of an element to be relative
to move the element from its default position. In the example below, a <div>
is moved from its bottom edge by 30px (top: -30px;
would do the same effect), and that's why the block overlaps with the last curved bracket of the source code (the curved bracket is made visible by styling the block with the CSS property opacity
):
div {
position: relative;
bottom: 30px;
}
One thing to note here is that you can see the space left by the moved block, since the area the block occupies does not vanish even after it's moved from its original position with position: relative;
. In the following example, left: 30%;
means to move from its left by 30% of its parent's width:
div {
position: relative;
left: 30%;
}
Fixed
When an element's position is set to fixed
, the element will stay in the same position in the browser window even if you scroll the page. Many designer found it useful for various reasons: Keep the navigation pane in the same position, always show a Go to top button in the bottom-right corner for users to navigate back to the beginning of a webpage very easily, etc. You are smart, so you know it must be similar to how you set the position of an element as relative
. Why not try it yourself?
Before you get too excited with your achievement, I need you to pay attention to the area originally occupied by the element...is it still there?
Absolute
As noted above, the position absolute
has two different meanings - absolute to its positioned parent/ancestor, or absolute to <body>
. Suppose that we have the following structure:
<body>
<article>
<section>
</section>
</article>
</body>
If <article>
is styled with position: relative;
and <section>
with position: absolute;
, the properties such as left
and top
refer to the edges of <article>
. However, if <section>
has a static
position, then the properties would refer to the edges of <body>
(or other non-static-positioned element in between). Let's try this on a separate page because I hate to ruin my webpage!
Inline vs. block vs. inline-block
In previous sections/units, we have been working on both inline elements (such as <a>
) and block-level elements (such as <p>
). The former creates a text flow from left to right, whereas the latter is arranged from top to down with a line break after each, thus interrupting the text flow if being inserted into the middle of texts (see HTML Basics for the demo). We usually don't have to manually style inline and block-level elements with CSS since Web browsers have the default style for these elements with the CSS property display
:
display: block; /* default for block-level elements */
display: inline; /* default for inline elements */
Of course, with this CSS property, one could convert a default block-level element into an inline element or the other way around. Or, you can make an element something in between with the inline-block
value:
display: inline-block; /* something between block and inline */
Here are the pairwise comparisons between these three values for the display
property for you to know the differences among them better:
inline vs. block
- height and width only work for block-level elements, and only block-level elements comes with a line break after itinline vs. inline-block
- the only difference is that height and width only work for inline-block elementsinline-block vs. block
- the only difference is that inline-block elements do not come with a line break, so they do not break the text flow.
One very common use of inline-block
, following the topic of position of this section, is to make it possible to juxtapose block-level elements in the same line and use the CSS property text-align
to adjust their horizontal position. This is convenient especially when you try to align these block-level elements to the center of their parent:
CSS is just a very flexible system to make sure that you can do it your own way!
Locate your <nav> and the container block
During the previous lectures, I've also already guided you to create a <nav>
element for the navigation pane of your website, and a <div>
element as the container of the main contents. With the CSS properties for positioning, I'll demonstrate how the layout of the current website is created. Here's our target template from the previous unit, with <nav>
on the left and <div>
on the right:
nav | div |
First of all, let's add an id
attribute to the <div>
element to give it a name of container
. This attribute does not change its appearance at all; it simply makes selection of this element in a CSS file easy. Note that you must be very discreet about using this strategy - we'll return to this issue below in More on selector.
<div id="container">
Next, let's give 70% of the entire browser window width to your container, and align it to the right edge of the window in the CSS file to give the space on the left to the navigation pane:
div#container {
width: 70%;
margin-left: 30%;
}
In the above style example, the hashtag #
is used to identify an element with an id
of a specific value. The selector can thus be translated as find a
. Then, the <div>
element that has an id
set to container
width
of 70%
refers to the width of the parent of the container, which is <body>
. Since <body>
is styled to have a width of 100% (the full browser window width), the container with a width of 70% occupies 70% of the browser window horizontally. Since I want to align the container to the right edge of the browser window, I set the left margin of the container to 30% - a gap of 30% browser window width to the left, and an element of 70% browser window width to the right...see the logic?
The empty space on the left is for the navigation pane, and I have a few goals here. First, I want it to occupy that 30% of the browser window width as well as the full browser window height. Second, I want it to fix to its position, so it is always aligned to the top and left edges of the browser window regardless of the scrolling action. I list the CSS properties you need for this styling below, and try it yourself first:
position
top
left
width
height
Still couldn't get it right? Select the following blank section for the answer:
nav {
position: fixed;
top: 0;
left: 0;
width: 30%;
height: 100%;
}
Now why don't you try the layout with the navigation pane at the top and container at the bottom, if this has been what you look for?
More on selector
In the previous section, I add an id
attribute to the container element so I can specifically select this element when trying to style it. However, this is actually not the best practice in Web design. The CSS selector allows an element to be identified from DOM in many different ways, and most of times you do not need any id
(or class
) attribute when you just try to style an element or a set of elements. Before I had learned more about how to use selectors and semantic HTML elements efficiently, I once made mistakes by only using <div>
elements and giving them specific ids just in order to style them, which is something you need to avoid.
(Adjacent) Siblings
For instance, you might have <p>
elements that are siblings of an either <h2>
or <h3>
heading as in the following example, and you want these <p>
elements to be styled differently.
<h2>
</h2>
<p>
</p>
<h3>
</h3>
<p>
</p>
Since the headings and the paragraphs are adjacent to each other, you can use the +
operator to denote the sibling relationship, and you don't need to give any specific id to the paragraphs immediately next to different headings:
h2 + p {
...
}
h3 + p {
...
}
There could also be non-adjacent siblings when, for instance, a <picture>
element is inserted between headings and paragraphs:
<h2>
</h2>
<picture>
</picture>
<p>
</p>
In this case, if you need to style the paragraphs below the headings, you can use the ~
operator to denote the non-adjacent sibling relation, such as:
h2 ~ p {
...
}
(Immediate) Child
In a similar vein, you and identify the ancestor-child relation in a CSS selector. In the following example, we have different <p>
elements inside <body>
and <section>
, which are thus immediate children of <body>
and <section>
:
<body>
<p>
</p>
</body>
<section>
<p>
</p>
</section>
Now, suppose that you only want to style the child paragraphs of <section>
. You can use the operator >
in the selector to denote this relation:
section > p {
...
}
Now, if the paragraph is not the immediate child of an ancestor element, you can still specify this grandparent-grandchild relation in the CSS selector, just with a space between the grandparent and the grandchild:
section p {
...
}
Pseudo-class and pseudo-elements
In CSS, there are various pseudo-class and pseudo-elements that you can use in the selector to style classes and elements that are not defined by HTML tags and attributes (and that's why they have a pseudo- prefix). Here are some frequently used pseudo-classes that are denoted using :
(for instance, selector:pseudo-class
):
:hover
- elements with the mouse cursor hovering over them:first-child
- the first immediate child of an element:last-child
- the last immediate child of an element:nth-child(n)
- the nth child of an element (n = nth):nth-last-child(n)
- the nth child of an element counting from the last child (n = nth):first-of-type
- the first element of the same sibling group:last-of-type
- the last element of the same sibling group:nth-of-type(n)
- the nth element of the same sibling group:not(selector)
- all elements that do not match (selector)
Pseudo-elements are very useful for styling the texts of an elements, which are denoted using ::
as listed below:
::first-line
- the first line of selected elements::first-letter
- the first letter of selected elements::before
- before selected elements (works with thecontent
property)::after
- after selected elements (works with thecontent
property)
Let me give you a small test here: What does the following style do? (select the line below the CSS style to find the answer)
body section:not(:last-child) > a::after {
content: '[link]';
}
/* Add texts '[link]' after every <a> that is the immediate child of a <section> that is not the last child of its ancestor <body>. */
The full list of pseudo-classes could be found on this MDN Web Docs page. Note that some of these pseudo-classes are still experimental and are not supported by all Web browsers. Check compatibility before using them in your own webpage.
Priority/Specificity
When elements are selected by multiple selectors in a CSS file and the properties in these styles are the same, one of these styles would have a higher priority to be applied to the selected elements. Let's start with the simpler case. Suppose that you carelessly style the background color of <body>
twice in your CSS file, the last style overrides the first one:
body {
background-color: white; /* overriden */
}
...
body {
background-color: grey;
}
...
You don't have to be worried about it if the styles selecting the same element(s) use different properties - the two styles will be merged into one.
In the next scenario, we have to deal with the specificity of a selector - the properties in a more specific selector override those in a less specific selector. Now, assuming we have an element specified with a class
attribute, such as <p class="intro">
, and we have the following two styles for the background color of <p>
. The second selector is more specific than the first one since it selects all <p>
with a class attribute of intro
, denoted with a period .
. Thus, although <p class="intro">
is selected by both selectors, the more specific one applies.
p {
background-color: white; /* overriden */
}
...
p.intro {
background-color: grey;
}
The above example seems pretty straightforward, so let take a look at a some more complex case. Now suppose we have a <p>
element inside a <section>
element, and we have the following two styles in our CSS file. Both styles will be applied to the <p>
elements to change its background color, but since the first selector is less specific than the second one, the first background-color
property is overriden by the second one.
p {
background-color: white; /* overriden */
}
...
section > p {
background-color: grey;
}
Finally, inline styling with the style
attribute could override the value of the same CSS properties specified for the selected element, but it doesn't cascade to its children that are specified with the same property:
<p style="background-color: red;"> <!-- more specific than the two styles above -->
For a more detailed explanation for the calculation of specificy, check Specifishity!
!important
When you need to override every more specific and conflicting style, just add !important
right after the value of a CSS property. However, this is not a recommended practice, because most of the time, you need to style your HTML elements based on their hierarchy, rather than blindly prioritize a CSS setting. But later, we will see that sometimes, we need !important
to allow CSS styles set by JavaScript to be overriden by the CSS styles set in CSS files.
p {
background-color: white !important;
}
...
section > p {
background-color: grey; /* more specific, but is overriden */
}
If you have multiple selectors as complex as the one you were just tested, then you should refer to the full system of how specificity is calculated on this MDN Web Docs page. Selectors in most small to medium website projects would be straightforward, I think.
Before the next unit...

Feel a little bit lost after all these? I believe you're not alone. Look at the sky, get a grip, and reflect on what you have just learned - they are really useful for your own bilingual website projects. It just takes time to digest, and you certainly will master these skills. Take a deep breath, and a new challenge is ahead of you.