Why does the page look tiny on my phone?
You have opened a web page on a phone and had to pinch and zoom to read one line. The page was made for a wide screen and the phone drew it small. A few lines of code tell the phone how to draw it properly, and this lesson looks at them.
By the end of this lesson
Note
I can find the parts of a web page that make it work on a phone.
Key words
- Viewport: the part of the screen the page is drawn in.
- Responsive: a layout that changes to fit the width of the screen.
- Media query: a rule in CSS that applies only when a condition is true, such as a minimum width.
- Manifest: a small file that tells a phone the name, icons and colours of a web app.
- Service worker: a script the browser keeps that can answer requests from a saved copy.
- Cache: a store of saved copies of files.
Starter: what you already know
Note
Answer in your head. 1. What does CSS do for a web page? 2. Is a finger bigger or smaller than a mouse pointer? 3. What happens to a web page when you have no network? Answers: it sets how the page looks; bigger; it usually fails to load, which is the problem the last step solves.
Before you start
Note
Press Start the lab on the bar at the top of this lesson and wait until it says it is running. There is one container, jupyter, and the terminal reaches its Python with docker exec jupyter, which runs one command inside it. The JupyterLab link opens its web page, port 8888, and the Preview link shows the habit tracker, port 8000. Each Run button below types its command into your lab's terminal, one after another in the same session. To watch them, or to type your own, press Open terminal on the bar.
The web app is a folder, and a small server shows it
ls app lists the web app: a page, its styles, its script, a manifest, a service worker and two icons. The second script asks the preview server for three of them and prints the answer. Each is 200, which means it was found, and the manifest has its own type, application/manifest+json. Now open the Preview link in your own browser, make the window narrow, and watch the layout change.
docker exec jupyter ls appShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
docker exec jupyter python3 steps/serve.pyShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
The viewport tag tells a phone how wide to draw
The script reads index.html and looks for a meta tag named viewport. It is found, with width=device-width, initial-scale=1: draw the page as wide as the screen, at normal size. Try it: delete that line in JupyterLab, save, run the script again, and it says MISSING. A phone would then draw the page as if the screen were far wider and shrink it.
docker exec jupyter python3 steps/viewport.pyShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Breakpoints change the layout at a width
The stylesheet is mobile first: the plain rules are the phone, and media queries add rules as the screen gets wider. The script finds three. Two are widths, 600 px and 900 px, and the third is not a width at all but a preference for dark mode. Make your browser window wider than 600 px and the form lines up in a row. Wider than 900 px and the list has two columns.
docker exec jupyter python3 steps/breakpoints.pyShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
A thumb needs room
A fingertip covers far more than a mouse pointer, and it hides what it presses. This lab uses 44 pixels as the line a button should reach. The script lists every size in the stylesheet: the Add button is 32 px high, the filter buttons 36 px, and the round done button 30 by 30, so four sizes are under 44. They are deliberately a little too small, and fixing them is your task.
docker exec jupyter python3 steps/touch.pyShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Check
Tip
Which breakpoint turns the list into two columns, and how many sizes are under 44 pixels? Answer: 900 px, and four.
A manifest lets a phone treat the page as an app
The manifest is a JSON file. The script checks seven fields. Six are present: the name, a short name for under an icon, the page to open first, how to display it (standalone, which means without the browser's own bars), the icons and the colour of the top bar. One is MISSING, background_color, the colour shown while the app starts. Both icon files exist. Whether a phone offers to install the app depends on the browser, so look for the option in your own browser's menu.
docker exec jupyter python3 steps/manifest.pyShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
A service worker lets the app open with no network
The service worker names a cache, habits-v1, and a list of eight files to save when it is installed. The script checks each one exists, and seven do. The eighth, /offline.html, does not. That is a real fault: if one file in the list cannot be saved, the whole install fails and nothing works offline. A browser only allows service workers on a secure address, so it may refuse this one on the preview link: your browser's console says which.
docker exec jupyter python3 steps/offline.pyShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
A common mistake
Warning
Many people think that if a page looks right in a narrow desktop window, it works on a phone. A narrow window shows the layout only. It does not show how big a thumb is, how slow a phone network is, or what the phone's own browser does. Use the narrow window to check the layout, then open the page on a real phone if you can.
A mobile web app next to a native app
A native app is built for one phone system and installed from a store. A mobile web app is a web page. It has one set of code for every phone, it is updated the moment you change the files, and a link opens it. It can keep data on the phone, work offline with a service worker and, in many browsers, be added to the home screen. It has less reach into the phone: what it may use, such as notifications or running in the background, depends on the browser and the phone, and the browser can clear its stored data. Choosing between them is a trade, not a contest.
Exit check
Tip
Answer without looking back. 1. Which tag tells a phone to draw the page as wide as the screen? 2. What does mobile first mean? 3. Which file gives an app its name and icons? 4. Why would a service worker fail to install if one listed file is missing? Answers: the viewport meta tag; the plain rules are for the phone and media queries add more for wider screens; the manifest; the list is saved in one go, so one failure stops the whole install.
For teachers
Tip
This lesson is a small example of a lesson worked in a lab: the steps and the Run buttons are the lesson, and the lab is each student's own copy. The lab is one service, JupyterLab, with a second port that previews the student's web app, and nothing here marks itself: the student hands in app/style.css with the small buttons made at least 44 pixels, and a sentence on what they changed and how they checked it in their own browser. Key learning points: 1. The viewport tag makes a page responsive on a phone. 2. Mobile first CSS adds media queries as the screen widens. 3. A manifest and a service worker make an installable, offline web app. Common mistake: trusting a narrow desktop window as a phone test. Equipment: the lab, a browser and, if possible, a phone. Tip: ask students to predict each output before they press Run. The files are written from fixed text, so every copy prints the same. Copy it into your own module and change it, or build one from scratch with the Lab menu in the lesson builder.