The next step after HTML

CSS: learn to style pages

HTML builds the skeleton, CSS gives it character: color, fonts, layout, animation. You write CSS and see the result instantly in a live pane. From selectors all the way to Flexbox and Grid.

Start
15 modulesLive resultCertificate
LIVE DEMO

Task: Round the box corners

border-radius: ?
Correct! See?

Welcome! CSS (Cascading Style Sheets) is the language for styling web pages. If HTML says what is on the page, CSS says how it looks: color, size, layout, spacing. In this course you will see every concept with your own eyes and try it yourself. Let's begin.

1
MODULE 1

Getting to know CSS

What CSS is and why you need it

A page written with HTML alone shows black text in a plain look. CSS adds color, a nice font and layout to that page. Below, the CSS code is on the left and the result on the right. Change the color value and watch the heading color switch instantly.

TaskGive the heading (h1) a color: write color: #2f6bed; in style.css. You'll see the result instantly in the right pane.
HTML (skeleton)<h1>Hello</h1>

Says what is there: heading, text, image. Plain, unstyled.

CSS (appearance)h1 { color: blue }

Says how it looks: color, size, layout. Brings the page to life.

Key idea: CSS is the styling layer for HTML. The same HTML can be shown completely differently with different CSS.

3 ways to attach CSS

You can add CSS to an HTML page in three ways. The best is method 3: a separate .css file. Because one file works for the whole site and the code stays clean. This course's editor works the same way: you write CSS in the style.css tab.

/* Method 1: inline (inside the element) */ <h1 style="color: blue">Hello</h1> /* Method 2: internal (a style tag inside head) */ <style> h1 { color: blue } </style> /* Method 3: external file (best) */ <link rel="stylesheet" href="style.css">
TaskGive the paragraph (p) a font size: write font-size: 20px;. Try for yourself how external CSS works.
Tip: In practice an external file (style.css) is almost always used. The inline method is only for small, one-off cases.

Syntax: selector, property, value

Every CSS rule has the same structure. First the selector (who we style), then property: value pairs inside curly braces. A semicolon (;) goes at the end of each pair.

h1 { color : blue ; } Selector who? Property what of it? Value how? inside { } = declaration block , ; = end of rule
selector { property: value; } = the basic form of a CSS rule
TaskGive the heading (h1) a color (color) and make the paragraph (p) bigger (font-size: 18px or larger).

Exercises

Now try on your own. In each exercise, write one CSS rule in style.css. If it's correct, the circle is confirmed with a green mark.

Module 1 quiz

To complete this module, answer at least 4 out of 5 correctly.

2
MODULE 2

Selektorlar va aniqlik

Element, class and id selectors

A selector tells CSS which element to style. There are three main types: by element name (no symbol), by class (with a dot .) and by id (with a hash #). A class can be given to several elements, while an id must be unique on the page.

p ELEMENT all p no symbol .karta CLASS class=karta dot, many elements #bosh ID id=bosh hash, unique
Three main selectors: element (no symbol), .class (dot), #id (hash)
TaskWith a class selector, make the .sarlavha text blue: .sarlavha { color: #2f6bed; }. Both .sarlavha elements change at the same time.
Key idea: a class can be given to many elements (reused), while an id goes to only one element per page.

Combinators: grouping, descendant, child, sibling

You can combine selectors to target things more precisely. For example, to select only an element inside another element, a descendant selector (a space) is used.

h1, h2 /* grouping: both h1 and h2 */ div p /* descendant: any p inside a div */ div > p /* child: a direct p child of div */ h1 + p /* adjacent: the first p after h1 */ h1 ~ p /* sibling: all p after h1 */
TaskMake only the paragraph inside .quti blue. Use a descendant selector for this: .quti p. It must not affect the paragraph outside.

Pseudo-classes: state and order

A pseudo-class targets an element's state or order. They are written with a colon (:). The most commonly used ones:

a:hover /* when the mouse is hovering */ li:first-child /* the first child element */ li:last-child /* the last child element */ li:nth-child(2) /* the 2nd child element */ li:nth-child(even) /* the even-positioned ones */ p:not(.tashqi) /* p's except .tashqi */
TaskWith a pseudo-class, make the first item of the list bold: li:first-child { font-weight: bold; }.
Try it: move your mouse over the button in the result pane, and the :hover state kicks in.

Pseudo-elements: ::before and ::after

With a pseudo-element you can add an extra piece before or after an element: ::before (before) and ::after (after). They are written with a double colon (::) and require the content property.

Element ::before ::after added before and after using content
::before adds a piece before the element, ::after after it
TaskShow some text before the name. Use ::before and content, for example: content: "Hello, ".

Specificity, cascade and inheritance

Sometimes several rules match one element. Which one wins? Specificity decides this: an id selector is stronger than a class, and a class is stronger than an element. An inline style (style="") is strongest of all.

element 1 .class 10 #id 100 inline 1000 left to right: specificity (weight) increases
Specificity weight: element < class < id < inline
TaskSpecificity rule: the id selector is strongest. Make #maxsus blue: #maxsus { color: #2f6bed; }. It wins over element and class too.
CASCADElast rule

If specificity is equal, the rule lower down (last) in the file wins.

INHERITANCEis inherited

Some properties (color, font) pass from the parent element to its children. Border and padding do not.

Be careful: !important forcibly overrides every rule. Use it as little as possible, because it makes fixing things harder later.

Exercises

Try selectors on your own. In each exercise, pick the right selector and write CSS.

Module 2 quiz

To complete this module, answer at least 5 out of 6 correctly.

3
MODULE 3

Ranglar va fon

Color formats and transparency

In CSS you can write a color in several ways. Screen colors are formed from a mix of red, green and blue light (RGB). The formats below can produce the same result, only their notation differs.

R G B
RGB: red, green and blue light combine to form other colors
color: tomato; /* named color */ color: #2f6bed; /* hex: # + 6 characters */ color: rgb(47, 107, 237); /* red, green, blue: 0-255 */ color: rgba(47,107,237,.5); /* + transparency: 0-1 */ color: hsl(217, 85%, 56%); /* hue, saturation, lightness */
TaskGive a color in hex format: .p2 { color: #2f6bed; }. Hex is a six-digit color code that starts with #.
Tip: the last number in rgba and hsla (from 0 to 1) sets transparency. 1 = fully opaque, 0 = invisible.

background-color and background-image

While color styles the text color, background-color paints the element's background. To put an image instead of a plain color, background-image is used.

TaskGive the box (.quti) a background color. Use background or background-color (for example: background: #2f6bed).

Background size and position

You can control how a background image is placed in the box: background-size (size), background-position (position), background-repeat (repeat). Two important sizes:

cover

The image fills the whole box. Edges are cropped if needed. No empty space remains.

contain

The whole image fits inside. Nothing is cropped, but there may be empty space around it.

TaskMake the image fit fully in the box: give .contain a background-size: contain;. See the difference from cover.
Note: background-repeat: no-repeat stops the image from repeating. This example image is loaded from the internet.

Gradients: smooth color transitions

A gradient is a smooth transition between two or more colors. It counts as an image, so it is given to background. There are three main types:

linear-gradient(to right, red, blue) /* linear */ radial-gradient(circle, red, blue) /* radial */ conic-gradient(red, blue, red) /* conic */
TaskGive the third box (.g3) a gradient background yourself. For example: background: linear-gradient(to right, #16a34a, #22c55e).
Good to know: conic-gradient rotates colors around a circle, handy for charts and clocks.

background shorthand and multiple layers

The background shorthand lets you write all background settings on one line. You can also stack several background layers by separating them with commas. The one written first becomes the top layer.

TaskGive the box (.karta) a gradient background: background: linear-gradient(120deg, #2f6bed, #1d4ed8);. The two colors blend smoothly into each other.
SHORTHANDbackground: ...

Writes color, image, size and position on one line. Shortens the code.

MULTIPLE LAYERSbg1, bg2

Layers separated by commas. For example, a semi-transparent gradient overlay on top of an image.

Exercises

Try colors and backgrounds on your own. Use different color formats and gradients.

Module 3 quiz

To complete this module, answer at least 5 out of 6 correctly.

4
MODULE 4

Matn va tipografika

font-family: font families

font-family sets which font the text is written in. Fonts fall into three big families, each with its own look and purpose.

Aa serif Aa sans-serif Aa monospace
serif (letters have little feet) · sans-serif (no feet, clean) · monospace (letters equal width)
font-family: Georgia, 'Times New Roman', serif; /* serif family */ font-family: Arial, Helvetica, sans-serif; /* sans-serif */ font-family: 'Courier New', monospace; /* monospace */
TaskGive the third paragraph (.mono) a monospace font: font-family: 'Courier New', monospace;. The letters become the same width.
Tip: this is a font stack. If the first font isn't found, the browser moves to the next. Always put a generic family (serif or sans-serif) at the end.

font-size and measurement units

font-size sets the text size. There are several units: px exact pixels, em relative to the parent element's font, rem relative to the root (html) font, % also relative.

font-size: 16px; /* exact pixels (absolute) */ font-size: 1.5em; /* 1.5x the parent font */ font-size: 1.5rem; /* 1.5x the html font */ font-size: 120%; /* 120% of the parent font */
TaskMake the text's (.matn) font-size 20px or larger.

Weight, italic and line spacing

font-weight sets the weight (normal/bold or from 100 to 900), font-style: italic makes text italic, and line-height controls the distance between lines.

font-weight: bold; /* or 700; normal = 400 */ font-style: italic; /* slanted (italic) text */ line-height: 1.6; /* line spacing */
TaskMake the second paragraph (.b) bold: font-weight: bold;.
Tip: a unitless number like line-height: 1.6 is multiplied by the font size and gives the most readable result.

Aligning and decorating text

Text can be styled in various ways: text-align alignment (left/center/right/justify), text-decoration underline, text-transform uppercase or lowercase, letter-spacing space between letters.

text-align: center; /* left / right / center / justify */ text-decoration: underline; /* underline; none = removes it */ text-transform: uppercase; /* UPPERCASE; lowercase = small letters */ letter-spacing: 2px; /* opens space between letters */
TaskCenter the heading (h2): text-align: center.

text-shadow and web fonts

text-shadow gives text a shadow: written in the order horizontal vertical blur color. You can also attach ready-made fonts from services like Google Fonts to the page.

TaskGive the heading (.soya) a text shadow: text-shadow: 2px 2px 0 #bcd0f7;.
/* Attach a ready-made font like Google Fonts (at the top of the CSS) */ @import url('https://fonts.googleapis.com/css2?family=Roboto'); font-family: 'Roboto', sans-serif; /* now this font works */
text-shadow2px 2px 4px #333

A shadow makes text stand out and look three-dimensional. You can also give several shadows separated by commas.

WEB FONT@import or <link>

Ready-made fonts give the page a distinctive look. Beyond system fonts, you can attach any font you want.

Exercises

Try text and typography on your own. Change size, weight and alignment.

Module 4 quiz

To complete this module, answer at least 5 out of 6 correctly.

5
MODULE 5

Box Model

Box Model: every element is a box

In CSS every element is like a four-layer box. From inside out: content (text), padding (inner space), border (edge) and margin (outer space). Understanding this structure is the foundation of layout.

margin border padding content
content (text) → padding (inner space) → border (edge) → margin (outer space)
TaskGive the box (.quti) a border: border: 3px solid #2f6bed;. This is the outer line of the box model.
Remember: padding opens space inside the box, while margin opens space outside it. A lot of confusion comes from mixing these two up.

padding: inner space

padding opens the space between the text (content) and the border. You can give it one or several values.

padding: 20px; /* all 4 sides the same */ padding: 10px 20px; /* top-bottom 10, left-right 20 */ padding: 5px 10px 15px 20px; /* top right bottom left */ padding-left: 12px; /* left side only */
TaskGive the box (.quti) a padding of 16px or more.

border and border-radius

border draws an edge on the box and has three parts: width style color. border-radius rounds the corners.

border: 2px solid #2f6bed; /* width style color */ border-radius: 12px; /* rounds the corners */ border-bottom: 3px dashed #999; /* bottom border only */ border-radius: 50%; /* turns a square into a circle */
TaskGive the second box (.b) rounded corners: border-radius: 14px;.
Styles: solid (solid line), dashed (dashed), dotted (dotted). For no border, write none.

margin and centering

margin opens space outside the box, between elements. Its most useful trick: horizontally centering a block that has a width using margin: 0 auto.

margin: 24px; /* outer space on all 4 sides */ margin: 0 auto; /* horizontal center (needs width) */ margin-bottom: 16px; /* bottom space only */
TaskCenter the box (.quti) horizontally: margin: 0 auto.

box-sizing: how a box is measured

By default width measures only the content, and padding and border add extra width (content-box). border-box instead includes padding and border inside the width, so the size stays exact.

box-sizing: content-box; /* default: width = content only */ box-sizing: border-box; /* width = content + padding + border */ * { box-sizing: border-box; } /* modern standard */
TaskGive the first box (.cb) box-sizing: content-box;. There, border and padding are added outside the width (total width 228px). .bb stays exactly 180px with border-box.
content-boxwidth = 180px

Total width = 180 + padding + border. So the real width comes out larger than you wrote. This causes confusion.

border-boxtotal width = 180px

Padding and border are counted inside the width, so the size stays exact. That's why many projects make this the standard.

Exercises

Try the box model on your own. Change padding, border and rounded corners.

Module 5 quiz

To complete this module, answer at least 5 out of 6 correctly.

6
MODULE 6

Display va joylashuv

display: how elements are laid out

display sets how an element flows on the page. block starts on a new line and takes the full width, inline sits side by side like text, inline-block combines both, and none hides the element completely.

block inline
block: each on a new line, takes the full width  ·  inline: side by side like text
display: block; /* new line, full width (div, p) */ display: inline; /* side by side, no sizable width (span, a) */ display: inline-block; /* side by side, but width/height apply */ display: none; /* hides completely (takes no space) */
TaskPlace the tags (.tag) side by side: display: inline-block;. The spans line up in one row and take a size.
Difference: display: none removes the element along with its space, while visibility: hidden hides it but keeps its space.

position: positioning types

position controls where an element sits. static is the default, relative shifts it from its own spot, absolute takes it out of the flow and places it relative to the nearest positioned ancestor, and fixed pins it to the screen.

position: static; /* default: normal flow */ position: relative; /* shifts from its spot with top/left */ position: absolute; /* relative to a positioned ancestor */ position: fixed; /* pinned to the screen, doesn't scroll */
TaskMake the target (.bola) position: absolute and place it in the corner of the parent box.

top/left and z-index

A positioned element is moved with top, right, bottom, left. When elements overlap, z-index decides which one is on top (larger number = on top).

position: absolute; top: 10px; left: 20px; /* 10 from the top, 20 from the left */ z-index: 10; /* higher number stays on top */
TaskBring the first box (.q1) to the very top: z-index: 5;. A larger z-index sits higher.
Attention: z-index only works on elements with a position set (other than static).

float and clear

float floats an element to the left or right, and text flows around it. Whole page layouts used to be built this way. clear drops the element after a floated one below it.

float: left; /* floats left, text flows on the right */ float: right; /* floats right, text flows on the left */ clear: both; /* drops below the floats */
TaskMake the image box (.rasm) float: left so the text flows on its right side.

overflow: excess content

When content doesn't fit its container, overflow controls what happens: should it overflow and show, be clipped, or get a scrollbar.

overflow: visible; /* default: overflows and shows */ overflow: hidden; /* clips the excess */ overflow: scroll; /* always a scrollbar */ overflow: auto; /* scroll when needed */
TaskGive the container (.quti) overflow: auto;. Text that doesn't fit becomes visible via scrolling.
hiddenclips it off

The part that goes outside the container is not shown. Useful for keeping the corners of images or cards clean.

autoscroll when needed

If the content fits it's plain, if not a scrollbar appears. The most convenient choice for long lists.

Exercises

Try layout on your own. Change display, position and overflow.

Module 6 quiz

To complete this module, answer at least 5 out of 6 correctly.

7
MODULE 7

Flexbox

Flexbox: flexible layout

Flexbox easily arranges elements along a row (or column). An element with display: flex becomes the container, and its direct children become flex items. There are two axes: the main axis (main) and the cross axis (cross).

main axis (main)
display: flex → container + 3 flex items, lined up along the main axis
.konteyner { display: flex; /* makes the children flex items */ }
TaskPlace the boxes side by side: give .qator a display: flex;. A flex container lines its children up in a row.
Important: display: flex only affects direct children, not grandchildren. Flexbox is the foundation of modern layout.

flex-direction: direction

flex-direction sets the direction of the main axis: whether the items sit in a row (horizontal) or a column (vertical).

flex-direction: row; /* default: left to right */ flex-direction: column; /* top to bottom */ flex-direction: row-reverse; /* right to left */ flex-direction: column-reverse; /* bottom to top */
TaskTurn .qator into a vertical column: flex-direction: column;. Now the boxes stack on top of each other.
Attention: when the direction changes, the main and cross axes swap too. In column, the main axis becomes vertical.

justify-content: the main axis

justify-content distributes the items along the main axis (horizontal in a row). It controls how the free space is shared.

justify-content: flex-start; /* to the start (default) */ justify-content: center; /* to the center */ justify-content: space-between; /* to the edges, equal between */ justify-content: space-around; /* equal space around each item */
TaskCenter the items along the main axis: justify-content: center.

align-items: the cross axis

align-items aligns the items along the cross axis (vertical in a row). Used together with justify-content, you can center any element.

align-items: stretch; /* default: stretches to fill */ align-items: center; /* cross-axis center */ align-items: flex-start; /* to the start (top) */ align-items: flex-end; /* to the end (bottom) */
TaskAlign the items to the center along the cross axis: align-items: center.

flex-wrap, gap and flex

If the items don't fit, flex-wrap: wrap moves them to the next line. gap puts space between items. And flex: 1 given to an item itself means it stretches to fill the free space.

flex-wrap: wrap; /* to the next line if they don't fit */ gap: 12px; /* space between items */ flex: 1; /* item fills the free space (on the item) */
TaskLet the third element (.katta) stretch to fill the free space: flex: 1;.
gapbetween items

If you use gap instead of margin, space falls only between items, not at the edges. Clean and easy.

flex: 1equal sharing

If several items get flex: 1, they share the remaining space equally. Ideal for flexible panels.

Exercises

Try Flexbox on your own. Change display, direction and alignment.

Module 7 quiz

To complete this module, answer at least 5 out of 6 correctly.

8
MODULE 8

CSS Grid

Grid: two-dimensional layout

While Flexbox is one-dimensional (a row or a column), Grid is two-dimensional: it handles rows and columns at the same time. An element with display: grid becomes a grid container, and grid-template-columns defines the column structure.

123 456
Grid = a grid of rows × columns; items drop into cells
.panjara { display: grid; grid-template-columns: 1fr 1fr 1fr; /* 3 equal columns */ }
TaskGive .panjara 3 equal columns: grid-template-columns: 1fr 1fr 1fr;. fr divides the free space into equal shares.
Rule: Grid is handier for complex page layouts (header, sidebar, content), and Flexbox for elements in a single row. Often the two are used together.

grid-template-columns and fr

grid-template-columns sets the number and width of columns. The fr unit means a share of the available free space: 1fr 1fr is two equal columns, while 2fr 1fr makes the first one twice as wide.

grid-template-columns: 200px 200px; /* 2 exact columns */ grid-template-columns: 1fr 1fr 1fr; /* 3 equal columns */ grid-template-columns: 2fr 1fr; /* one is 2x as wide */
TaskMake the grid display: grid and create 3 equal columns with grid-template-columns.

gap and repeat()

gap puts space between cells (works in both grid and flex). repeat() writes repeating columns in short form: repeat(3, 1fr) = 1fr 1fr 1fr.

gap: 12px; /* space between rows and columns */ grid-template-columns: repeat(3, 1fr); /* 3 equal columns (short form) */ grid-template-columns: repeat(4, 100px); /* 4 columns of 100px */
TaskAdd space between the grid cells: give .panjara a gap: 12px;.
Powerful trick: repeat(auto-fit, minmax(120px, 1fr)) automatically adjusts the number of columns to the screen width (a responsive gallery).

grid-column and grid-row: spanning

An item can be stretched across several columns or rows. grid-column: span 2 makes the item 2 columns wide. You can also give it by line numbers: grid-column: 1 / 3.

grid-column: span 2; /* spans across 2 columns */ grid-row: span 2; /* spans across 2 rows */ grid-column: 1 / 3; /* from line 1 to line 3 */
TaskStretch the first cell (.katta) across 2 columns with grid-column: span 2.

grid-template-areas: named layout

The most visual Grid method: you name each cell and draw the layout like an ASCII picture. This makes it easy to place a header, sidebar and content.

.panjara { grid-template-areas: "header header" "sidebar content"; } .head { grid-area: header; }
TaskName the layout: give .panjara a grid-template-areas (head on top, side and main below). Each element drops into its place via grid-area.
Grid2 dimensions

Whole page layout: rows and columns at once. Ideal for header, sidebar, content, footer.

Flexbox1 dimension

Elements in a single row: a navbar, a row of buttons, cards. Also used inside a Grid.

Exercises

Try Grid on your own. Change columns, gap and spanning.

Module 8 quiz

To complete this module, answer at least 5 out of 6 correctly.

9
MODULE 9

Responsive dizayn

Responsive: adapting to every screen

Responsive design shows a page just as nicely on phone, tablet and computer. Its foundation is relative units: % (of the parent element), vw/vh (screen width/height), rem (relative to the root font).

desktop tablet phone
One page: side by side on a wide screen, stacked on a phone
width: 60%; /* 60% of the parent width */ font-size: 1.2rem; /* 1.2x the html font */ width: 80vw; /* 80% of the screen width */
TaskGive .quti a relative width: width: 60%;. It takes 60 percent of the parent container and adapts as the screen changes.
Basics: without the <meta name="viewport"> tag in the HTML, responsive doesn't work. Choose relative units instead of fixed px.

max-width: preventing overflow

max-width caps an element's largest width. max-width: 100% keeps an image or box from spilling outside its container. This is one of the most important rules of responsive design.

max-width: 100%; /* doesn't exceed the container (image) */ max-width: 600px; /* keep the text line from getting too long */ min-width: 200px; /* keep it from shrinking too much */
TaskFit the box (.rasm) into the container with max-width: 100% (so it doesn't overflow).

@media: styles based on the screen

The @media rule applies different styles depending on the screen width. Rules for narrow screens are written with max-width, and rules for wide screens with min-width. This is called a breakpoint.

/* for narrow screens (phone) */ @media (max-width: 600px) { .karta { background: #1d4ed8; } }
TaskGive .karta a border-radius: 10px;. The @media rule below changes the background color when the screen is narrower than 600px (already in the code).
Try it: the result pane below is narrow, so the mobile style (dark blue) shows. Change the breakpoint number and watch the effect.
max-widthdesktop-first

First the wide-screen style, then rules for narrow screens are added. The older approach.

min-widthmobile-first

First the phone style (the base), then additions for wide screens. The modern recommendation.

Mobile-first approach

The modern recommendation: first write the base style for the phone, then add extras for larger screens with @media (min-width: ...). This keeps the code clean and lightweight.

.karta { /* base = phone */ font-size: 14px; padding: 16px; } @media (min-width: 600px) { /* wide-screen addition */ .karta { font-size: 20px; } }
TaskGive .karta a base (mobile) background: background: #2f6bed;. The @media (min-width: 600px) increases padding and font on larger screens.
Reason: there are many phone users. Starting simple for them first, then adding extras, is faster and more reliable.

clamp(), min() and max()

These functions give flexible sizing without media queries. clamp(min, ideal, max) keeps a value between two limits: clamp(16px, 4vw, 28px) text changes with the screen, but never smaller than 16px or larger than 28px.

font-size: clamp(16px, 4vw, 28px); /* flexible, bounded */ width: min(90%, 500px); /* the smaller is chosen */ padding: max(16px, 3vw); /* the larger is chosen */
TaskGive the heading (.quti) a flexible size: font-size: clamp(18px, 5vw, 28px).

Exercises

Try responsive rules on your own. Set constraints with max-width and min-width.

Module 9 quiz

To complete this module, answer at least 5 out of 6 correctly.

10
MODULE 10

Animatsiya va transform

transform: moving and rotating

transform moves, rotates, enlarges or skews an element without breaking the layout. It is the foundation of animation because it runs very fast.

original translate rotate scale
translate (move) · rotate (rotate) · scale (enlarge)
transform: translate(20px, 10px); /* moves */ transform: rotate(15deg); /* rotates */ transform: scale(1.2); /* enlarges */ transform: skew(10deg); /* skews */
TaskRotate .quti: transform: rotate(8deg);. transform turns, enlarges or moves an element.
Combining: you can write several together: transform: rotate(10deg) scale(1.1). The order matters.

transition: smooth change

transition makes a change smooth (animated) rather than instant. For example, a button's color changes gradually on :hover. It's written in the order transition: property duration curve.

transition: 0.3s; /* all changes 0.3s */ transition: background 0.4s ease; /* background only, smooth */ transition: transform 0.3s, color 0.2s; /* multiple properties */
TaskGive the box (.quti) a transition: 0.3s, then hover your mouse over it (it changes smoothly).

Interactivity with :hover

When :hover and transition are used together, you get lively, pleasant buttons. When the mouse comes over it, the element changes nicely.

.tugma { transition: 0.25s; } .tugma:hover { transform: translateY(-3px); /* lifts upward */ }
TaskGive the button a smooth transition: .tugma a transition: 0.25s;. The :hover rule below moves smoothly thanks to the transition.
Try it: hover your mouse over the button in the result pane; it lifts and changes color.

@keyframes and animation

For complex, self-running animation, @keyframes defines the stages (from/to or 0%–100%), and animation applies it to an element.

@keyframes aylanish { from { transform: rotate(0); } to { transform: rotate(360deg); } } .element { animation: aylanish 2s linear infinite; }
TaskApply the ready animation to the box (.quti): animation: aylanish 2s linear infinite.

animation settings

To fully control an animation there are separate properties: duration, timing curve, how many times it repeats, and delay.

animation-duration: 2s; /* duration */ animation-timing-function: ease-in-out; /* timing curve */ animation-iteration-count: infinite; /* how many times (or 3) */ animation-delay: 0.5s; /* delay */
TaskApply the pulse animation to .yurak: animation: puls 1.2s ease-in-out infinite;. @keyframes puls is ready in the code.
timing-functionease / linear

How the motion speed changes. ease is more natural, linear is uniform. ease-in-out is used a lot.

iteration-countinfinite / 3

infinite repeats endlessly; if a number is given, it runs that many times and stops.

Exercises

Try animation and transform on your own. Change transform, transition and opacity.

Module 10 quiz

To complete this module, answer at least 5 out of 6 correctly.

11
MODULE 11

Ilg'or CSS

CSS variables (--var)

CSS variables let you store a value in one place and use it in many. They are declared in the form --name (usually in :root) and called via var(--name). Change the color in one place and it updates everywhere.

--rang var(--rang) var(--rang) var(--rang)
One variable → many elements get the same value
:root { --asosiy: #2f6bed; /* declaring the variable */ } .tugma { background: var(--asosiy); } /* using it */
TaskSet the root's --asosiy variable to #22c55e (green) — the box turns green too.

calc(): math inside CSS

calc() does math by mixing different units. For example calc(100% - 40px) subtracts 40px from the full width — very useful where you can't add a percentage to pixels.

width: calc(100% - 40px); /* full width minus 40px */ font-size: calc(1rem + 2px); /* adding units */ height: calc(100vh - 60px); /* screen height minus header */
TaskGive .quti a width with calc(): width: calc(100% - 40px);. calc computes by combining different units.
Attention: spaces around operators (+, -) are required: calc(100% - 40px) is correct, calc(100%-40px) doesn't work.

filter: visual effects

filter gives an element blur, brightness, grayscale and other effects. It works especially well with images.

filter: blur(4px); /* blurs */ filter: grayscale(100%); /* makes it black and white */ filter: brightness(1.4); /* brightens */ filter: drop-shadow(0 4px 6px #999); /* shadow */
TaskBlur the .a box: filter: blur(2px);. filter gives an element a visual effect (blur, grayscale).
Combining: you can write several effects together: filter: grayscale(50%) brightness(1.2).

object-fit and aspect-ratio

object-fit: cover fills the container with an image without distorting its ratio (it crops the excess). aspect-ratio gives an element a fixed ratio — like a 16 / 9 video frame, for example.

object-fit: cover; /* fills while keeping the ratio */ object-fit: contain; /* fits it entirely */ aspect-ratio: 16 / 9; /* fixed ratio */
TaskGive the box (.quti) an aspect-ratio: 16 / 9 — its height is computed automatically.

clip-path: shape clipping

clip-path clips an element from a rectangle into another shape (triangle, circle, polygon). Only the shown area is visible.

clip-path: circle(50%); /* circle */ clip-path: polygon(50% 0, 0 100%, 100% 100%); /* triangle */ clip-path: inset(10px); /* inset clipping */
TaskMake a triangle from .uchburchak: clip-path: polygon(50% 0%, 0% 100%, 100% 100%);. clip-path cuts an element into any shape.
circle()circle

Clips the element into a circle shape. An easy solution for avatars or round buttons.

polygon()polygon

Any shape from points: triangle, rhombus, arrow. For creative sections.

Exercises

Try advanced CSS on your own. Work with calc, filter and aspect-ratio.

Module 11 quiz

To complete this module, answer at least 5 out of 6 correctly.

12
MODULE 12

Zamonaviy CSS va yakuniy loyiha

Dark mode (dark theme)

Modern sites work in two themes. @media (prefers-color-scheme: dark) detects the choice in the user's system, and CSS variables let you switch the colors in one place.

light dark
One site, two themes: switches automatically with a variable + prefers-color-scheme
:root { --fon: white; --matn: #0f172a; } @media (prefers-color-scheme: dark) { :root { --fon: #0f172a; --matn: white; } }
TaskSwitch the color via the theme variable: set --fon to #22c55e in :root. One variable controls the whole theme (dark mode works on this basis).
Secret: write colors via var(--fon) rather than directly. Then to switch themes you only need to update the variables.

:has() — the parent selector

A long-awaited feature: :has() selects a parent element based on what's inside it. For example, you can style a card that contains an image differently — previously this could only be done with JavaScript.

.karta:has(img) { border: 2px solid #2f6bed; } /* if it contains an image */ label:has(input:checked) { font-weight: bold; } /* if it's checked */
TaskGive a card that contains .belgi a blue background: .karta:has(.belgi) { background: #2f6bed }.

CSS nesting (writing rules inside rules)

Modern CSS allows writing rules nested inside one another — just like Sass, but in pure CSS. The & symbol refers to the parent selector. This keeps related rules together and makes the code tidy.

.karta { padding: 16px; & p { color: gray; } /* same as .karta p */ &:hover { background: #eef; } /* .karta:hover */ }
TaskPlace a nested rule inside .karta and make the paragraph yellow: & p { color: gold; }.

BEM: a class naming convention

In large projects, the BEM convention is used so class names don't clash: block__element--modifier. It ensures names are clear, unique and understandable.

.karta { } /* Block: an independent component */ .karta__sarlavha { } /* Element: a part (double underscore __) */ .karta--faol { } /* Modifier: a state (double dash --) */
TaskStyle the modifier class: give .karta--faol a border: 2px solid #2f6bed;. In BEM, --faol denotes the card's state.
Benefit: from the name .karta__tugma you can immediately see it's a tugma (button) inside a karta (card). No name collisions.

Accessibility (a11y) and final tips

A good site should be usable by everyone. Enough contrast between text and background, a visible focus for the keyboard, and reduced animation for motion-sensitive users — these are the marks of professional work.

:focus-visible { outline: 2px solid #2f6bed; /* make keyboard focus visible */ } @media (prefers-reduced-motion: reduce) { * { animation: none; } /* reduce motion */ }
TaskGive the button cursor: pointer; (it signals that it's interactive). The :focus-visible rule below draws a visible ring when focused with Tab (important for keyboard users).
Contrastreadability

Light text on a light background can't be read. When choosing colors, make sure the contrast is enough.

Semanticsthe right tag

Use <button> for a button, <h1> for a heading — CSS styles, HTML gives meaning.

Well done! You've mastered the fundamentals of modern CSS. In the next modules, forms, measurement units and 3D transforms await you, and at the end there's a final exam.

Exercises

Try modern CSS on your own. Work with nesting, accent-color and outline.

Module 12 quiz

To complete this module, answer at least 5 out of 6 correctly.

13
MODULE 13

Formalarga uslub berish

Styling input, textarea and select

Form elements (a text field, a multi-line textarea, a dropdown select) come with the browser's old, ugly default look. With CSS you give them a border, inner spacing, corner radius and font to match your site's style. If you set width: 100%, the field takes up the full container.

input, textarea, select { width: 100%; padding: 10px 12px; border: 1px solid #cbd5e1; border-radius: 8px; font-size: 15px; /* prevents zoom on mobile */ }
TaskGive the input field a border-radius: 8px so its corners are rounded.
Tip: if you set the font to 16px or larger, the page won't auto-zoom when the field is tapped on a phone.

Focus, hover and disabled states

You should show a field differently when the user clicks into it (focus), hovers over it (hover), or when the field is turned off (disabled). For :focus, make the browser's default ring nicer with outline or box-shadow. :focus-visible shows only when arriving via the keyboard.

input:focus { border-color: #2f6bed; outline: none; box-shadow: 0 0 0 3px #bfdbfe; /* soft focus ring */ } input:disabled { background: #f1f5f9; cursor: not-allowed; }
TaskGive the field inner space: give input a padding: 11px 13px;. The :focus and :disabled rules below style the field based on its state (try clicking the field).
Attention: if you write outline: none, be sure to show focus another way with box-shadow or border. Otherwise a keyboard user won't know where they are.

Validation states and placeholder

CSS can style based on the form's state: :checked (checked), :required (required), :valid / :invalid (filled in correctly or wrong), :placeholder-shown (not yet typed). And the ::placeholder pseudo-element styles the gray text in an empty field.

input::placeholder { color: #94a3b8; font-style: italic; } input:invalid { border-color: #ef4444; /* red if filled in wrong */ } input:valid { border-color: #22c55e; /* green if correct */ }
TaskGive input a border: border: 2px solid #cbd5e1;. The :valid and :invalid rules change the border color when the email is correct or wrong.
:requiredrequired

Highlights fields that must be filled in, for example with an asterisk or color.

:checkedchecked

Works when a checkbox or radio is checked. The main tool for making custom buttons and toggles.

accent-color and custom checkbox

You can paint checkbox, radio and slider (range) colors with your brand color using a single property: accent-color. This is the easiest way. If you need a fully custom look, turn off the default shape with appearance: none and draw your own from scratch.

/* Easiest: just change the color */ input[type="checkbox"], input[type="radio"] { accent-color: #2f6bed; width: 18px; height: 18px; }
TaskGive the checkbox (input) an accent-color: #2f6bed so its mark is blue.

Form structure and layout

A nice form is not only color but also structure. Link each field with a <label> (clicking it focuses the field). Group related fields in a <fieldset>. Flexbox is very handy for layout: flex-direction: column and gap line the fields up evenly with equal spacing.

form { display: flex; flex-direction: column; gap: 14px; /* equal spacing between fields */ } label { font-weight: 600; margin-bottom: 4px; }
TaskStack the form vertically: give form a display: flex; and flex-direction: column;. The label and input pairs line up one below another.
Convenience: if you link <label for="email"> and <input id="email">, clicking the label also focuses the field, making it easier to use.

Exercises

Try form styling on your own. Work with border radius, accent-color and inner spacing.

Module 13 quiz

To complete this module, answer at least 5 out of 6 correctly.

14
MODULE 14

O'lchov birliklari (units)

px and absolute units

There are two kinds of sizing in CSS: absolute (fixed) and relative (dependent on something). px (pixel) is the most used absolute unit: a single dot on the screen. It gives precise control, so it fits borders (border) and fine sizes very well. pt (point) is used mainly for print.

border: 1px solid #ccc; /* px is ideal for a thin border */ width: 300px; /* exact, fixed width */ border-radius: 8px;
TaskGive the box an absolute width: width: 300px;. A pixel (px) is a fixed unit independent of the screen.
Rule: don't use only px everywhere. For text and layout, relative units (rem, %) make the page flexible and respectful of user settings.

Percent (%): relative to the parent element

% is a relative unit: the value is computed relative to the parent element. width: 50% takes half of the parent's width. When the parent widens or narrows, the child changes with it. That's why percent is the foundation of responsive layouts.

.ota (280px) width: 50%
The child takes half the parent's width (140px)
TaskGive the child (.bola) width: 50% so it takes half the parent (200px).

em: relative to the current font

em is a relative unit: relative to the current (parent) element's font-size. If the parent font is 16px, then 1em = 16px, 2em = 32px. When the font changes, sizes given in em change proportionally with it. Watch out: em compounds - it can grow larger in nested elements.

.ota { font-size: 16px; } .bola { font-size: 2em; } /* 2 x 16px = 32px */ .bola { padding: 1em; } /* inner space matching the font */
TaskGive the child (.bola) font-size: 2em. The parent is 16px, so the text becomes 32px.

rem: relative to the root

rem (root em) is always computed relative to the root (html) element's font-size. The default html font is 16px, so 1rem = 16px, 2rem = 32px. The key difference from em: rem does not compound, it's always taken from the root. That makes it predictable and preferred in modern projects - you can scale the whole site from one place (the html font).

html { font-size: 16px; } /* root size */ .sarlavha { font-size: 2rem; } /* 32px, regardless of the parent */
emto parent font

Depends on the parent element. When nested, it compounds and grows unexpectedly.

remto the root

Always tied to the html font, stable. The most reliable choice for text sizes.

TaskGive the heading (.sarlavha) font-size: 2rem. The root is 16px, so it becomes 32px.

viewport units: vw, vh

Viewport units are relative to the screen (browser window) size: vw = 1% of the viewport width, vh = 1% of its height. So 100vw is the full screen width and 100vh the full screen height. vmin and vmax are 1% of the smaller or larger dimension. They are very handy for large headings and full-screen sections.

font-size: 5vw; /* text grows as the screen widens */ height: 100vh; /* full screen height */ width: 90vw; /* 90% of the screen width */
TaskGive the banner a viewport unit: font-size: 5vw;. vw equals one percent of the screen width (5vw = 5 percent); widen the window and the font grows.
Powerful pair: viewport units work best together with clamp() (module 9): clamp(18px, 5vw, 40px) adapts text smoothly within limits.

Exercises

Try units on your own. Size things with percent, em and rem.

Module 14 quiz

To complete this module, answer at least 5 out of 6 correctly.

15
MODULE 15

3D Transformlar

perspective: creating a 3D scene

In module 10 we saw 2D transforms. 3D transforms also move an element in depth (closer to or farther from the screen). For this you first need a 3D scene: give the perspective property to the parent element. It represents the distance between the eye and the screen. A small value (like 400px) gives a strong, exaggerated effect, while a large value gives a gentle one.

eye perspective = sense of depth
perspective gives the parent element 3D depth
.sahna { perspective: 800px; /* parent: opens 3D space */ }
TaskGive the scene (.sahna) perspective: 800px to open a 3D space.

rotateX, rotateY, rotateZ

In 3D space an element can rotate around three axes: rotateX around the horizontal axis (tilts forward or back), rotateY around the vertical axis (turns sideways, like a door), and rotateZ in the screen plane (ordinary 2D rotation). Use these together with perspective and you get a real sense of volume.

transform: rotateX(45deg); /* tilts forward */ transform: rotateY(45deg); /* turns sideways */ transform: rotateZ(45deg); /* rotates in the plane */
TaskGive the box (.quti) transform: rotateY(40deg) to turn it sideways.

translateZ and translate3d

translateZ moves an element along the Z axis - closer to the screen (positive value) or farther from it (negative). This is only visible with perspective: a positive translateZ makes the element bigger (closer). translate3d(x, y, z) moves along all three axes at once.

transform: translateZ(60px); /* comes closer to the screen */ transform: translate3d(10px, 0, 40px); /* x, y, z together */
TaskBring .quti closer along the Z axis: transform: translateZ(50px);. Thanks to perspective, the box looks bigger (closer).
Note: the translateZ effect is only visible if the parent element has perspective. Without perspective, Z movement isn't noticeable.

preserve-3d and backface-visibility

Two important helper properties are needed for 3D. transform-style: preserve-3d keeps an element's children in 3D space (otherwise they stay flat, 2D). backface-visibility: hidden hides the element's back side - it isn't visible when the element flips over. This is especially needed for flipping cards.

.karta { transform-style: preserve-3d; /* children stay in 3D */ } .yuz { backface-visibility: hidden; /* the back side is hidden */ }
TaskGive the card (.karta) transform-style: preserve-3d.

3D flip card (project)

Now let's combine all the knowledge. To make a flipping card: perspective on the parent, transform-style: preserve-3d and transition on the card, backface-visibility: hidden on both faces, and the back face starting at rotateY(180deg). If you apply rotateY(180deg) to the whole card on hover, it flips smoothly and shows its back. Hover your mouse over the card below!

TaskFor a 3D flipping card: give .karta a transform-style: preserve-3d;. Then hover your mouse over the card and it rotates 180 degrees.
perspectiveon the parent

Opens 3D depth. Without it, the rotation looks flat and lifeless.

backface-visibilityon the faces

Ensures the back side isn't visible when the card flips over.

Exercises

Try 3D transforms on your own. Work with perspective, rotate and preserve-3d.

Module 15 quiz

To complete this module, answer at least 5 out of 6 correctly.

FINAL EXAM

Practical exam and final test

Part 1: Practical exam

This is the biggest challenge of the course. Click the button and a full-screen code studio opens: you write CSS on the left, and on the right there are "Reference" (the finished design you need to achieve) and "Result" (your live result) tabs. The HTML is ready; just write CSS to build the profile card from the reference 1:1. The exam passes when all 10 requirements are met.

You write CSS on the left and compare Reference and Result on the right.

Part 2: 50-question final test

50 questions across all 15 modules. To reach the certificate, answer at least 40 out of 50 correctly.

CertificateWhen you complete all 15 modules and the final exam, your personal certificate will unlock here.