frontend · starter · 3d
Личная страница-портфолио
Собери одностраничный сайт о себе на чистом HTML, CSS и капле JavaScript — без фреймворка, без сборки, просто файлы, которые открываются в браузере. В итоге у тебя будет что показать, и ты по-настоящему поймёшь каждую строчку, потому что написал её сам.
Результат
Адаптивное одностраничное портфолио (hero, о себе, проекты, контакты), которое хорошо выглядит на телефоне и ноутбуке и имеет один маленький интерактивный элемент, подключённый на JavaScript, — открываемое прямо из файла index.html.
Этапы
0/4 · 0%- 01Свёрстай структуру на HTML
Начни со скелета: один index.html с понятными, осмысленными секциями — шапка с твоим именем, абзац «о себе», список из двух-трёх проектов и ссылка для связи. Используй настоящие семантические теги (header, main, section, nav, footer), а не кучу div. Пока без стилей: простая чёрно-белая страница, которая уже читается сверху вниз и имеет смысл, — это и есть результат шага. Открой файл прямо в браузере, чтобы увидеть его.
Критерии готовности- index.html открывается в браузере и показывает твоё имя, абзац о себе, список проектов и ссылку для связи.
- Страница использует семантические элементы (header/main/section/footer), а не только вложенные div.
- 02Оформи стилями на CSS
Подключи таблицу стилей и сделай страницу своей: выбери шрифт, пару цветов, удобные отступы и разложи секции через flexbox, чтобы всё выравнивалось, а не складывалось криво. Целься в спокойное и читаемое, а не в кричащее. Навык, который ты тренируешь, — видеть страницу как коробки, которым можно задать размер, отступы и выравнивание; как только это щёлкнет, любая вёрстка станет легче.
Критерии готовности- Подключённый CSS-файл задаёт типографику, цвета и отступы, и хотя бы одна секция свёрстана через flexbox.
- Страница выглядит продуманной и читаемой, а не как документ со стилями по умолчанию.
- 03Сделай, чтобы работало на телефоне
Большинство увидит твою страницу с телефона, поэтому она должна держаться на узкой ширине. Добавь meta-тег viewport, затем через media query поправь раскладку для маленьких экранов — сложи колонки в столбец, уменьши hero, добавь отступов. Меняй ширину окна браузера и смотри, как страница подстраивается. Адаптивность — это не отдельная страница, а тот же HTML, который решает раскладываться иначе, когда места меньше.
Критерии готовности- На странице есть meta-тег viewport и хотя бы один media query, меняющий раскладку на узких экранах.
- На ширине телефона ничего не вылезает по горизонтали и контент остаётся читаемым.
- 04Оживи страницу на JavaScript
Добавь один маленький интерактивный штрих на чистом JavaScript — переключатель тёмной темы, кнопку «скопировать email» или мобильное меню, которое открывается и закрывается. Найди элемент, подпишись на клик и измени что-то на странице в ответ. Ограничься одной хорошо сделанной фичей. Это базовый цикл всей фронтенд-интерактивности: найти элемент, отреагировать на событие, обновить DOM. Освой его один раз — и дальше всё то же самое.
Критерии готовности- Клик по твоему элементу заметно меняет страницу (тема, состояние «скопировано» или открытое/закрытое меню).
- JavaScript находит элементы и навешивает обработчик клика — без инлайнового onclick в HTML.
Рубрика
| Джуниор | Миддл | Сеньор | |
|---|---|---|---|
| Семантический HTML и доступность | Секции есть и страница читается сверху вниз; вместо семантических элементов используются обёртки div там, где подошли бы семантические теги. | header / main / section / nav / footer используются корректно; у картинок есть alt, ссылки навигируются клавиатурой, и контраст соответствует WCAG AA (≥4.5:1 для основного текста). | Интерактивный элемент (переключатель / меню) управляется клавиатурой с видимым фокусом, правильными ARIA-ролью и атрибутами aria-expanded / aria-controls, и страница проходит аудит доступности axe-core или Lighthouse без критических нарушений. |
| Адаптивная вёрстка без переполнения | Meta-тег viewport присутствует; страница сужается, но некоторые элементы вылезают или текст становится нечитаемо мелким на ширинах телефона. | Хотя бы один media query меняет раскладку для маленьких экранов; ничто не вылезает по горизонтали на ширине телефона (320 пкс) и весь контент остаётся читаемым. | Раскладка использует внутренние размеры (min-content / max-content / clamp) или флюидные единицы, чтобы точки перелома были исключением, а не правилом; страница проверена на 320, 768 и 1440 пкс без переполнения и с корректным размером tap-target (≥44 пкс) для интерактивных элементов. |
| Бюджет производительности и CWV | Страница загружается, но у картинок нет явных размеров (риск CLS), шрифты блокируют рендер, и данные Lighthouse или PageSpeed не собирались. | У картинок явные width/height (нет CLS), шрифты используют font-display: swap, и запуск Lighthouse показывает LCP < 2.5 с и CLS < 0.1 на мобильной симуляции. | Героическое изображение предзагружается с fetchpriority='high', изображения ниже сгиба используют loading='lazy', страница задеплоена и реальный запуск PageSpeed / CrUX подтверждает целевые CWV (LCP < 2.5 с, CLS < 0.1, нет layout shift от подмены шрифта). Ты можешь назвать, какой ресурс устанавливает каждый CWV и что сломает бюджет. |
Эталонный разбор (спойлер)
Ценность семантического HTML: семантические элементы бесплатно дают браузеру (и вспомогательным технологиям) структурный контракт — nav неявно является landmark-регионом, button с клавиатуры фокусируется и срабатывает на Enter/Space без JS, header подразумевает роль banner. Замена div+role работает, но требует ручной реализации всего этого поведения, и ошибиться легко.
Корневые причины CLS на странице-портфолио: три самых распространённых источника layout shift — картинки без явных размеров (браузер не резервирует место до загрузки), веб-шрифты (текст переплывает при подмене на кастомный шрифт) и поздно вставляемый контент (баннер cookie или виджет аналитики, сдвигающий hero вниз). Исправление всех трёх не стоит ничего в размере кода и переводит LCP и CLS с красного на зелёный.
Адаптивность без точек перелома: большинство проблем переполнения на узких экранах возникает из-за фиксированных пиксельных ширин. Замена width: 400px на max-width: 100% или использование clamp() для размеров шрифта убирает необходимость во многих точках перелома. min-width: 0 на flex-детях предотвращает переполнение flex-контейнера дочерним элементом с длинным текстом — один из самых частых багов первых адаптивных вёрсток.
Сделай по-сеньорски
- Задеплой бесплатно (GitHub Pages, Netlify или Cloudflare Pages), чтобы у страницы появился настоящий URL, который можно положить в резюме.
- Пройдись по доступности и Lighthouse: проверь контраст цветов, добавь alt к картинкам и убедись, что страницей можно полностью пользоваться с клавиатуры.