1. Mobile design acceptance checklist
The markup developer is the “eyes” between the designer and the developer. Before starting the markup, it’s worth reviewing the layout and giving feedback to the designer.
Differences of the mobile interface
- No hover — a finger can’t “hover” over an element without tapping
- Larger click area — the minimum size of an interactive element is ~48×48 px
- No keyboard — entering text is harder, it’s better to use checkboxes, radio buttons, toggles
- Gestures — swipe, zoom; but gestures are rarely used on websites
Simulating hover on mobile
On iOS, simulating hover requires an interactive element — <a> or <button>. A plain <span> won’t work. On Android it works with any element.
What to check in the layout
- Size of interactive elements (min. 48×48 px)
- No horizontal dropdown lists
- Text readability without zooming
- Sufficient spacing between buttons / links
- Elements with two values → checkbox or toggle
- Few options → radio buttons instead of a dropdown
2. meta viewport — configuring the viewport
Without the viewport meta tag, a mobile browser renders the site as a desktop one (with a width of ~980 px), and the user has to zoom manually.
<meta name="viewport" content="width=device-width, initial-scale=1.0">
| Parameter | Value | Description |
|---|---|---|
width |
device-width |
Viewport width = the device’s recommended width (accounting for DPR) |
initial-scale |
1.0 |
Initial zoom level (1.0 = 100%) |
minimum-scale |
number | Minimum allowed zoom level |
maximum-scale |
number | Maximum allowed zoom level |
user-scalable |
yes / no |
Allow/disallow zooming by the user |
user-scalable=no and maximum-scale=1 prevent users from enlarging small text or examining images. This harms the site’s accessibility.3. Media queries in CSS — extended syntax
A media query in CSS can be combined with a device type:
@media screen {
body {
font-size: 14px;
}
}
A more complex query — with a width condition:
@media (max-width: 480px) {
/* Styles for screens up to and including 480px */
}
Strategy: fewer media queries is better
Instead of two paired queries (up to 480 and from 481) — keep the base CSS for mobile and one query from 481:
/* Base styles — always apply (mobile) */
.sidebar,
.content {
width: 100%;
}
/* From 481px — columns are added */
@media (min-width: 481px) {
.content { width: 75%; }
.sidebar { width: 25%; }
}
4. Critical CSS
Critical CSS is the minimal set of styles needed to render the site’s first screen. It’s embedded directly into a <style> inside <head>.
Why?
- An external CSS file takes time to load
- Inline CSS renders instantly along with the page
- The user sees the first-screen content before the main CSS loads
What affects speed
| Factor | Recommendation |
|---|---|
| Number of files | Fewer files — fewer server requests |
| File size | Minification, image optimization |
| CSS complexity | Simpler selectors — faster rendering |
| Deferred loading | Lazy loading for images below the first screen |
5. The em unit — the current element’s font size
1em = the current element’s font-size value. If an element has no explicit font-size, the value is inherited from the parent up the chain to the root element.
.box {
font-size: 20px;
width: 10em; /* 10 × 20 = 200px */
padding: 1em; /* 1 × 20 = 20px */
}
font-size, all sizes in em will change proportionally. This can lead to an unexpected enlargement or reduction of the element.6. The rem unit — the root element’s font size
1rem = the font-size value of the <html> element (not <body>). Unlike em, rem doesn’t depend on the nesting context.
html {
font-size: 10px; /* 1rem = 10px, easy to calculate */
}
.box {
width: 30rem; /* 300px */
padding: 1.5rem; /* 15px */
}
When rem is convenient
- Version for the visually impaired — we change only the
font-sizeonhtml, and everything scales - Global scaling — if the client asks to “shrink everything by 1.5×”, it’s enough to change a single value
html { font-size: 10px; } — then a value from the layout (for example, 961px) is simply divided by 10 → 96.1rem.7. Where to use which units
| Unit | Type | Where to use |
|---|---|---|
px |
Relative | The main unit — everything that doesn’t fall into the other categories |
% |
Relative | Columns (25%, 33%, 50%, 75%, 100%) — only when the division is visually apparent |
em |
Relative | Rarely; when there’s a clear proportion relative to the font size |
rem |
Relative | Version for the visually impaired, global scaling |
vw, vh |
Relative | Responsiveness (introduced in the next lessons) |
cm, mm, in |
Absolute | Only for print (@media print) |
pt |
Absolute | Print media, typography (rarely on the web) |
8. Useful CSS shorthands
inset — a shorthand for positioning
The inset property replaces setting top, right, bottom, left all at once:
.overlay {
position: absolute;
/* Instead of top: 0; right: 0; bottom: 0; left: 0; */
inset: 0;
}
The syntax is analogous to margin: one value — for all sides, two — for vertical/horizontal, four — for each side separately.
Logical properties: margin-inline and padding-block
Logical properties set spacing relative to the text direction, not the physical sides of the screen:
| Logical property | Physical equivalent (for LTR) |
|---|---|
margin-inline |
margin-left + margin-right |
padding-block |
padding-top + padding-bottom |
margin-inline-start |
margin-left (for LTR) / margin-right (for RTL) |
.card {
margin-inline: auto; /* Horizontal centering */
padding-block: 2rem; /* Top and bottom spacing */
}
place-items and place-content — quick centering
In a Grid container, place-items is a shorthand for align-items + justify-items, and place-content — for align-content + justify-content:
.container {
display: grid;
place-items: center; /* Centers content on both axes */
}
display: grid; place-items: center; — two lines for perfect centering of elements both horizontally and vertically.9. Don’t over-optimize with em
A common mistake is to see that a heading is 2.5 times larger than the text and replace font-size with 2.5em. It works until the designer changes one size without the other.
Bad optimization
.service p {
font-size: 16px;
}
.service h2 {
font-size: 2.5em; /* 40px, but depends on the parent's font-size */
}
Better — explicit values
.service p {
font-size: 16px;
}
.service h2 {
font-size: 40px;
}
@media (max-width: 768px) {
.service p { font-size: 14px; }
.service h2 { font-size: 28px; }
}
10. Margin collapsing
In the normal flow (without flex), the vertical margins of adjacent elements don’t add up, they collapse — the larger of the two remains.
.block-1 {
margin-bottom: 70px;
}
.block-2 {
margin-top: 30px;
}
/* The distance between blocks = 70px (not 100px!) */
| Context | Vertical margins |
|---|---|
| Normal flow | Collapse (the larger one remains) |
| Flex container | Add up (the sum) |
| Grid container | Add up (the sum) |
11. Additional media features
Besides min-width / max-width, there are other media features:
| Feature | Example | Description |
|---|---|---|
orientation |
@media (orientation: landscape) |
Landscape orientation of the device |
orientation |
@media (orientation: portrait) |
Portrait orientation of the device |
min-height |
@media (min-height: 600px) |
Minimum viewport height |
max-height |
@media (max-height: 400px) |
Maximum viewport height |
min-width / max-width. Orientation — less often. Height — even less often, because the page scrolls vertically.12. The aspect-ratio and orientation media features
aspect-ratio
Defines the width-to-height ratio of the display area (viewport). It’s written as a fraction:
@media (min-aspect-ratio: 16/9) {
/* Styles for wide screens */
}
It supports the min- and max- prefixes. To figure out which ratio is larger — convert the fraction to a decimal: 16/9 = 1.78, 16/10 = 1.6. So, min-aspect-ratio: 16/9 doesn’t include 16:10 monitors.
Popular aspect ratios
| Ratio | Where it’s found |
|---|---|
| 4:3 | Old CRT monitors, designer monitors |
| 16:9 | The most popular: Full HD, HD, 4K |
| 3:2 | Microsoft Surface, some modern laptops |
| 16:10 | MacBook Pro, some laptops (more height — handier for code) |
| 21:9 | Ultrawide monitors, the cinematic format |
orientation
Defines the orientation of the device. It takes two values:
portrait— vertical (height > width)landscape— horizontal (width > height)
@media (orientation: landscape) {
/* Styles for horizontal orientation */
}
Combined media query
For correct operation across different devices, a combination is often needed:
@media (min-width: 641px),
(orientation: landscape) and (max-width: 640px) {
/* Large screens OR horizontal phones */
.menu {
display: flex;
flex-wrap: wrap;
}
.menu__item {
width: 49%;
}
}
Just orientation: landscape isn’t enough — on a vertically held iPad (a large screen!) the elements would be one per row. And a vertically rotated monitor would also register as portrait.
13. Markup developer’s tools
| Tool | Purpose |
|---|---|
| Chrome Workspaces | CSS changes in DevTools are saved to a file automatically — without manual copying |
| Pixel Perfect (extension) | Overlays the layout image on top of the site for pixel-by-pixel comparison |
letter-spacing |
Adjusts the spacing between letters (a negative value can be used for “tightening”) |
| Figma | Lets you copy partial CSS properties of elements, speeding up markup |
14. Summary table
| Topic | Key points |
|---|---|
| meta viewport | width=device-width, initial-scale=1.0 — a required tag for responsive markup |
| Media queries in CSS | @media (min-width: ...) — Mobile First; @media (max-width: ...) — Desktop First |
| Critical CSS | First-screen CSS is embedded in <style> for instant rendering |
| em | 1em = the current element’s font-size; depends on context |
| rem | 1rem = the <html> element’s font-size; independent of nesting |
| CSS Shorthands | inset (positioning), margin-inline/padding-block (logical), place-items (centering) |
| Margin collapsing | In the normal flow vertical margins collapse; in flex/grid — they don’t |
| overflow: hidden | A crutch for horizontal scrolling — better to find the root cause |
| aspect-ratio | The width/height ratio of the viewport; supports min-/max- |
| orientation | portrait (vertical) / landscape (horizontal) |