Хорошее портфолио веб-разработчика заменяет резюме: вместо списка навыков ты сразу даёшь нанимающему ткнуть, покрутить, прочитать кейс и понять, кого именно зовут на собеседование. Парадокс в том, что собрать такое портфолио без референсов почти невозможно — слишком много вопросов: что показывать, как описывать роль, нужно ли заходить в WebGL или хватит аккуратной типографики, делать «вау» или содержательно. Ниже — десять разных ответов на эти вопросы от практикующих разработчиков, чьи сайты регулярно попадают в подборки Awwwards, FWA и CSS Design Awards и обсуждаются в твиттере.

Заранее два дисклеймера. Первый: «крутое портфолио» — это не обязательно 3D в браузере и физика. В списке намеренно намешаны полярные подходы — от 3D-эффектов и геймификации до строгого accessibility-first минимализма и простого контент-лендинга. Каждый подход решает свою задачу найма, и тебе выбирать, какой ближе. Второй: для джуна полезнее не копировать визуал, а понять, какие маленькие приёмы складываются в большое впечатление — поэтому в конце каждого блока есть «что забрать с собой».

Bruno Simon

Bruno Simon

Бруно Симон — французский creative developer, автор курса Three.js Journey и преподаватель WebGL (WebGL — это API для 3D-графики в браузере через GPU) с более чем семилетним стажем. Его портфолио — это не сайт со скриншотами, а маленькая игра: вы садитесь за руль радиоуправляемой машинки и катаетесь по 3D-миру, врезаясь в кубики с проектами. Версия 2019 года взяла Awwwards Site of the Day и Site of the Month, после чего автор полностью переписал сайт с нуля — текущая версия живёт в открытом репозитории folio-2025 под лицензией MIT, и вы можете залезть в исходники.

Стек, который видно в package.json переписанной версии, поучителен сам по себе: three для рендера, @dimforge/rapier3d для физики (Rapier — физический движок на Rust, скомпилированный в WebAssembly, заменил cannon.js из первой версии), howler.js для звука, gsap для анимаций и vite как сборщик. Модели делаются в Blender, прогоняются через @gltf-transform (это набор утилит для оптимизации GLTF — формата 3D-моделей для веба), сжимаются до WebP-текстур и ETC1S-компрессии — поэтому сайт с десятками объектов весит порядка нескольких мегабайт. В кейс-стади на Medium Бруно подробно разбирает, почему он держит два параллельных мира: примитивные коллайдеры в физическом движке и красивые меши в Three.js, синхронизируя их каждый кадр.

Если вы джун и заходите изучать этот сайт, есть три конкретные точки входа. Первое — инерция управления машинкой: антенна на крыше не анимирована руками, она наклоняется в сторону, противоположную ускорению, и пружинит обратно к центру; чем сильнее отклонение, тем сильнее возвращающая сила. Это классическая модель, которую полезно один раз написать самому — пригодится для любых «живых» интерфейсов, от скролл-эффектов до курсоров. Второе — лоадер: посмотрите, как сайт сначала тянет минимум ассетов, показывает интерактив, и только потом догружает остальное; в исходниках это видно по разделению на этапы инициализации. Третье — Blender → сцена: откройте папку с .blend-файлами в репо и проследите путь одного объекта от моделирования до экспорта в GLTF и появления в коде через GLTFLoader.

Свет в сцене — отдельный урок прагматизма. Динамических источников света почти нет, вместо них используются матcap-текстуры: маленькая круглая картинка, которая красит поверхность в зависимости от того, как нормаль (направление, в которое «смотрит» полигон) расположена относительно камеры. GPU при этом не считает реальное освещение, а просто делает выборку из текстуры — дёшево и стабильно держит 60 fps даже на слабых устройствах. Оранжевое «отражение» от пола подделано через скалярное произведение нормали с осью «вверх», блики на солнце — двумя проходами размытия по краям экрана. Это полезный антипаттерн против установки «возьму PBR, оно само красиво» — на вебе бюджет на кадр жёсткий, и быстрые трюки часто выигрывают у физически корректных вычислений.

// Идея антенны: смещение пропорционально ускорению,
// плюс пружина, тянущая обратно к нулю.
const acceleration = velocity.clone().sub(prevVelocity)
antenna.offset.add(acceleration.multiplyScalar(-0.15))   // толкаем в противоход
antenna.offset.multiplyScalar(0.92)                       // демпфирование (трение воздуха)
antenna.mesh.rotation.x = antenna.offset.z
antenna.mesh.rotation.z = -antenna.offset.x

Звук собран на howler.js с маленькой хитростью: при столкновении проигрывается не один файл, а случайный из пачки похожих, со случайной громкостью и скоростью — поэтому ухо не успевает устать от повтора. Идея портфолио, по словам автора в интервью Mux, выросла из детства с Micro Machines на PlayStation и радиоуправляемых машинок — изначально это была демка для студентов, а не карьерный проект. Главный вывод для джуна: впечатляющий результат складывается из десятка простых приёмов (матcaps, примитивные коллайдеры, рандомизация звуков, GLTF-сжатие), а не из одного «магического» алгоритма. Залезайте в репозиторий, ставьте npm run dev и читайте код — он специально написан как учебный.

Adam Argyle

Adam Argyle

Адам Аргайл — Design Engineer в Shopify (команда Polaris), бывший Chrome DevRel в Google и действующий участник CSS Working Group — рабочей группы W3C, которая решает, как должен развиваться CSS. До Google он годами публиковался на CSS-Tricks и вёл выступления на конференциях; на сайте argyleink.com лежит его старое портфолио — статичный HTML с автозапускающимся видео-фоном и сеткой проектов на flex-row, по нему хорошо видно, насколько за последнее десятилетие изменился фронтенд. Сам Адам сейчас пишет на nerdy.dev (собран на Deno + Fresh, рендерится на сервере, отдаёт минимум JS) — туда стоит ходить за свежими постами про anchor positioning, view transitions и scroll-driven animations.

Главный его публичный продукт — Open Props: библиотека из ~500 готовых CSS-переменных (цвета, размеры, тени, easings, шкалы типографики). Это не фреймворк в духе Bootstrap — никаких классов и компонентов, только токены. Подключаешь файл и пишешь padding: var(--size-3) вместо магических чисел.

@import "https://unpkg.com/open-props";

.card {
  padding: var(--size-4);
  border-radius: var(--radius-3);
  box-shadow: var(--shadow-3);
  background: var(--surface-2);
  transition: transform var(--ease-out-3) 200ms;
}

Дополнительно у него есть gui-challenges — репозиторий из 36 разобранных компонентов (карусели, табы, диалоги, тултипы, переключатели), каждый с упором на доступность, адаптивность и кросс-браузерность. К каждому компоненту прилагается видео и статья на web.dev — формат «бери и разбирай», очень полезный для джунов.

Из тем, которые Адам активно двигает: CSS Cascade Layers (слои каскада — механизм @layer, который позволяет явно расставить приоритет групп стилей и больше не воевать со специфичностью), селектор :has() (родительский селектор — позволяет стилизовать элемент в зависимости от того, что внутри него лежит) и View Transitions API (API плавных переходов между состояниями DOM — браузер сам делает кроссфейд между «до» и «после»). Он один из основных евангелистов этих фич — выступал с ними на CSS Day в Амстердаме, на Google I/O, на SmashingConf и в подкасте Syntax. Если хочется обзорный материал, его профиль на Smashing Magazine собирает ссылки на ключевые статьи и доклады.

Что стоит вынести джуну. Во-первых, изучить, как устроена цветовая и размерная шкала в Open Props — это рабочий пример того, как должна выглядеть система дизайн-токенов на чистых CSS-переменных, без препроцессоров. Во-вторых, прогнать пару компонентов из gui-challenges от начала до конца: открыть HTML и CSS, понять, почему диалог фокусируется именно так, почему карусель работает на scroll-snap, а не на JS, и где в коде живёт поддержка prefers-reduced-motion. В-третьих, посмотреть его свежие демки на CodePen — там много экспериментов на anchor positioning и scroll-driven анимациях, которые ещё пару лет назад требовали JS, а теперь делаются 10 строками CSS.

Henry Heffernan

Henry Heffernan

Генри Хеффернан — дизайн-инженер из США, сейчас работает в Vercel, а до этого был художником и геймдевом. Его сайт-визитка — это не лендинг, а целая 3D-сцена: рабочий стол с ЭЛТ-монитором, который при загрузке «бутится» в духе старой Windows. На экране включается фейковый рабочий стол с иконками, по нему можно таскать окна, читать про проекты, послушать радио и даже запустить DOOM прямо в браузере. Свой портфолио-проект Генри выложил с подписью «huge thanks to @bruno_simon for the inspiration and his #threejsjourney» — то есть прямо признаёт, откуда брал референс и где учился.

Под капотом — связка из двух репозиториев: portfolio-website для 3D-оболочки и portfolio-inner-site для содержимого «монитора». 3D-часть собрана на чистом Three.js (WebGL — 3D-графика через GPU прямо в браузере), без обёрток вроде React Three Fiber: TypeScript, GSAP и tween.js для анимаций, camera-controls для управления камерой, собственные шейдеры на GLSL и glslify для эффектов на экране. То, что показывается «внутри монитора» — это отдельное React-приложение, которое крутится по адресу os.henryheffernan.com и встраивается в 3D-сцену через iframe.

Главный трюк сайта — как HTML-контент попадает на 3D-плоскость. Three.js умеет рендерить не только пиксели через WebGL, но и обычные DOM-элементы — для этого есть CSS3DRenderer, который трансформирует HTML-узлы CSS-матрицами в трёхмерном пространстве. Генри создаёт <iframe> с внутренним сайтом, оборачивает его в CSS3DObject и кладёт ровно туда, где в 3D-модели находится стекло монитора. Получается живой, кликабельный экран — без всяких костылей в духе «отрендерить страницу в текстуру».

import { CSS3DObject } from 'three/examples/jsm/renderers/CSS3DRenderer.js';

const iframe = document.createElement('iframe');
iframe.src = 'https://os.henryheffernan.com/';
iframe.style.width  = screen.width  + 'px';
iframe.style.height = screen.height + 'px';

const screenObject = new CSS3DObject(iframe);
screenObject.position.set(monitorX, monitorY, monitorZ);
scene.add(screenObject);

«Операционка» внутри экрана — это не библиотека-скин типа xp.css, а полностью самописный оконный менеджер на React. В репозитории видны компоненты Window.tsx, DesktopShortcut.tsx, DragIndicator.tsx, ResizeIndicator.tsx, Toolbar.tsx и ShutdownSequence.tsx — то есть таскание, ресайз, фокус-перехват, z-index и даже последовательность выключения сделаны руками. DOOM на ретро-мониторе работает через js-dos — это эмулятор DOSBox, скомпилированный в WebAssembly. Атмосферу добивает звук: AudioManager подкладывает к кликам мыши mouse_down.mp3 и mouse_up.mp3, к печати — шесть разных семплов клавиш, к загрузке — startup.mp3, плюс фоновый офис и радио.

Что отсюда забрать джуну. Первое: «3D на сайте» не обязано быть монолитной WebGL-сценой — можно держать обычные React-страницы и просто проецировать их на 3D через CSS3DRenderer, тогда формы, ссылки и iframe-эмуляторы работают нативно. Второе: миксовать рендереры можно — WebGL для модели монитора и теней, CSS3D для самого экрана, обычный DOM для оверлеев. Третье: разделение на два репозитория («оболочка» и «начинка») — нормальный приём, внутреннее приложение даже доступно по отдельному поддомену и работает само по себе. Четвёртое: тактильность делается мелочами — клик мыши без звука и клик со звуком воспринимаются как два разных интерфейса. Сайт в своё время показывали на Hacker News как «Show HN: 3D Portfolio website with late 90s aesthetic, made with Three and React», его же подсветил Бруно Симон в Wall of Fame своего курса Three.js Journey — для джуна, который только подходит к WebGL, это удобный «эталон второго шага» после tutorials.

Jhey Tompkins

Jhey Tompkins

Jhey Tompkins (Джей Томпкинс) — design engineer, в прошлом DevRel в команде Chrome CSS/UI у Google, потом design engineer в Vercel, сейчас работает в дизайн-студии Shopify. Его кратко описывают так: берёт сложные интерфейсные задачи и превращает их в «как ты вообще это сделал?»-моменты. Если ты в твиттере хоть раз видел «вот это на чистом CSS, без JS» и ахнул — с большой вероятностью это его пен. Соавтор спеки CSS Anchor Positioning и активный участник продвижения новых CSS-возможностей в публичное поле.

Сайт jhey.dev устроен непривычно для блога: главная — это не лента статей, а хаб со ссылками на его профили. Основной контент живёт на CodePen (сотни демок), в X/Twitter (@jh3yy) и в виде статей на сторонних площадках — Smashing Magazine и CSS-Tricks. Для junior это полезная модель портфолио: один публичный «двор» с демками, который сам по себе работает как резюме.

Из подписей на Smashing — «The Path To Awesome CSS Easing With The linear() Function», «3D CSS Flippy Snaps With React And GreenSock», «What If Our Sliders Actually Slid?». Тематика повторяется: scroll-driven animations (анимации, привязанные к прокрутке через animation-timeline и animation-range), view transitions (плавные переходы между состояниями страницы), 3D-флипы карточек, кнопки с микровзаимодействиями, ценовые таблицы-переключатели на чистом CSS через :has(). Расшифровка: :has() — родительский селектор, который проверяет, что внутри элемента; например, «покрасить форму, если внутри есть невалидный инпут» — теперь без единой строчки JS.

Минимальный пример в его духе — карточка, которая «знает», что её чекбокс отмечен, и сама подсвечивается:

.card:has(input:checked) {
  outline: 2px solid #859900;
  background: #f4fff0;
  transform: scale(1.02);
  transition: all .2s ease;
}

Что отсюда забрать junior-у. Первое: открой любой его пен и нажми «Edit on CodePen» — это самый быстрый способ изучить новый CSS, потому что у Jhey весь эффект собран в 30–80 строк без библиотек, видно каждое свойство. Второе: посмотри, как делаются scroll-driven animations — это нативный аналог библиотек вроде GSAP ScrollTrigger, и он уже работает в Chrome без полифиллов. Третье: разберись с :has() — он закрывает огромную пачку случаев, где раньше тянули JS только чтобы «если внутри X, то родителю класс Y». Это та самая категория навыков, которая отделяет «верстаю по макету» от «понимаю, что умеет современная платформа».

Lynn Fisher

Lynn Fisher

Линн Фишер — дизайнер и фронтенд-разработчик из Финикса, и её личный сайт — самая известная в комьюнити «лаборатория редизайнов». Уже больше десяти лет подряд она каждый год полностью перерисовывает lynnandtonic.com с нуля: контент почти не меняется, а вот визуал, вёрстка и используемые техники — каждый раз другие. Текущая версия помечена римской цифрой (на момент написания — v. XIX), и это буквально «номер итерации»: счётчик ежегодного ритуала.

Ценность для джуна — в архиве. Линн собрала все прошлые версии на одной странице: lynnandtonic.com/archive.html. Открываешь — и видишь живую эволюцию веб-дизайна: от ранних трёхколоночных вёрсток с iframe до иллюстрированных интерфейсов на чистом CSS с grid, clip-path, conic-gradient и SVG-фильтрами. Какие-то года — это pure-CSS без единой строчки JavaScript, какие-то — с интерактивом и анимациями по скроллу. Отличная пища для понимания, как менялись возможности браузера и как одна и та же задача (показать портфолио) решается десятком разных способов.

Второй большой проект Линн — A Single Div. Это галерея рисунков, где каждая иллюстрация сделана из ровно одного <div>. Всё остальное — фоновые градиенты, тени, ::before и ::after, box-shadow вместо пикселей, трансформы. Звучит как ограничение ради ограничения, но на практике это лучший в открытом доступе учебник по тому, на что вообще способны свойства CSS, если перестать думать о них как о «коробочках с текстом». Линн ведёт этот проект больше десяти лет, и автор не раз выступала на конференциях (CSSConf, dotCSS, CSSDay) с разборами того, как такие штуки собираются.

Что забрать с собой джуну. Первое: пролистай архив редизайнов подряд — это бесплатный мини-курс «история фронтенда на одном домене». Каждая версия — отдельная техника, отдельный набор приёмов, есть смысл открыть DevTools и поковырять. Второе: попробуй сделать свой single-div: одна фигура (логотип, иконка, простой пейзаж) — только из CSS, без SVG и картинок. Это быстро ставит руку на градиенты, псевдоэлементы и тени. Третье, методическое: посмотри, как Линн годами сохраняет контент между редизайнами — портфолио, тексты, ссылки переезжают, а визуальная оболочка меняется. Это хороший паттерн и для личного сайта, и для любого продукта: данные отдельно, представление отдельно.

И главное — сам ритуал. Раз в год переписать свой сайт с нуля, не трогая контент, — отличный способ держать руку на пульсе новых CSS-фич и одновременно иметь публичное доказательство роста. Не обязательно делать это каждый год, но завести себе «v. II» уже стоит: разница между твоей нынешней вёрсткой и переписанной через полгода скажет о прогрессе больше, чем любое резюме.

Brittany Chiang

Brittany Chiang

Бриттани Чанг — Senior Frontend Engineer, Accessibility в компании Klaviyo: до этого она шесть лет росла от инженера до Lead Engineer в бостонской студии Upstatement, а ещё раньше прикладывала руку к веб-плееру Apple Music. Это важный контекст: её портфолио — не парадная витрина дизайнера, а демонстрация инженерной зрелости человека, который каждый день пишет компонентную библиотеку и думает про a11y (a11y — сокращение от accessibility, доступность интерфейса для людей с инвалидностью и для скринридеров). Зайди на brittanychiang.com — и через 10 секунд поймёшь, почему этот сайт уже много лет фигурирует в подборках «лучшие портфолио фронтендеров».

Текущая версия собрана на Next.js с Tailwind CSS, шрифт — Inter, хостинг — Vercel. Цветовая палитра — глубокий тёмно-синий фон и бирюзовый акцент: спокойно, контрастно, без визуального шума. Структура максимально утилитарная: Hero с короткой самопрезентацией, About, Experience с табами по местам работы, Projects, Writing. Никаких параллаксов, никаких «вау-анимаций» — только аккуратные fade-in при скролле и подсветка активного пункта навигации. Именно эта сдержанность и делает сайт эталоном: ничего не отвлекает от текста и кода.

Отдельная история — архив v4.brittanychiang.com, четвёртая итерация портфолио на Gatsby и styled-components. Исходники открыты в репозитории bchiang7/v4 на GitHub — около 8.3k звёзд и 4.2k форков, лицензия MIT. Именно поэтому шаблон стал одним из самых клонируемых портфолио в мире: можно форкнуть, поменять контент и получить рабочий сайт за вечер. Бриттани в README прямо разрешает форки и просит лишь поставить ссылку на оригинал — честный социальный контракт open source.

Главная инженерная фишка — accessibility-first подход. Первое, что встречает скринридер на странице, — skip-to-content link, ссылка-«перемотка» прямо к основному контенту мимо навигации. Это маленький паттерн, который входит в WCAG (WCAG — Web Content Accessibility Guidelines, международный стандарт доступности веба) и который большинство джунов вообще не ставят. Вот как выглядит минимальная разметка такой ссылки:

<a href="#main-content" class="skip-link">
  Skip to content
</a>

<nav>...</nav>

<main id="main-content" tabindex="-1">
  <!-- основной контент -->
</main>

Если ты джун и хочешь учиться на этом портфолио — вот три конкретных направления. Первое: разбери секционный layout — как Hero, About и Experience сделаны через семантические <section> с понятными id, а не через бесконечные <div>. Второе: посмотри, как реализована подсветка активной секции в боковой навигации — это классический паттерн на IntersectionObserver (IntersectionObserver — браузерный API, который сообщает, когда наблюдаемый элемент попадает в viewport или выходит из него, без ручного слушания scroll). Третье: пройдись Tab-ом по сайту без мыши и обрати внимание на focus-кольца, порядок фокуса и тот самый skip-link — это и есть «доступность руками», а не на словах. Форкни bchiang7/v4, открой DevTools и читай код секциями — это, пожалуй, лучший доступный учебник по «как должен выглядеть production-grade сайт фронтендера».

Rauno Freiberg

Rauno Freiberg

Эстонский интерфейсный инженер, сейчас Staff Design Engineer в Vercel, до этого собирал интерфейс браузера Arc в The Browser Company. Сам Rauno называет себя «соединительной тканью между дизайном и разработкой» — то есть человеком, который не рисует макеты в Figma, а сразу пишет работающий прототип в HTML, CSS и JavaScript. Его сайт rauno.me — это, по сути, лаборатория микровзаимодействий: каждый второй блок там можно потянуть, отпустить, свайпнуть и почувствовать, что у него есть инерция, как у физического предмета.

Главная страница для джуна — rauno.me/craft. Это галерея из пары десятков самодостаточных демок: Adaptive Precision (слайдер, который становится точнее, если отвести курсор подальше от трека), Spatial Tooltip (всплывашка, которая сама понимает, с какой стороны ей вылезти), Liquid Swipe (страница перелистывается, как разворот книги), Gooey Tooltip и Blur Reveal (SVG-фильтры, благодаря которым иконки не «вспыхивают», а как будто перетекают). Каждая демка — это упражнение на одну конкретную деталь, и именно так Rauno советует учиться: брать одно взаимодействие и переписывать его подряд несколько раз, пока ощущение не станет «правильным».

Сопроводительное чтение — его эссе Invisible Details of Interaction Design. Там разобраны принципы, которые он применяет в каждой своей анимации: жест должен сохранять импульс и угол, с которым его «бросили» (как карточка приложения в iOS); лёгкое действие срабатывает прямо во время свайпа, а разрушительное — только когда палец отпустили; интерфейс обязан переживать «экстремальный ввод», когда пользователь жмёт всё подряд и дёргает мышью как попало. Отдельно стоит отметить два связанных проекта Rauno: командное меню cmdk (написал Paco Coursey, Rauno внедрил его в Vercel и помогает поддерживать — именно благодаря этой связке шаблон «⌘K-палитра» стал индустриальным стандартом) и его собственная книга-курс по интеракшен-дизайну Devouring Details — 23 главы плюс готовые React-компоненты.

Что забрать в работу прямо сегодня. Первое — изучи пружинную анимацию: spring physics — это анимация по модели физической пружины, у неё нет фиксированной длительности, она задаётся параметрами stiffness (жёсткость), damping (затухание) и mass (масса). Самый короткий путь — поставить библиотеку Motion for React (бывший Framer Motion) и собрать игровую площадку с тремя ползунками, которые меняют эти три параметра в реальном времени; через час экспериментов разница между «робот» и «живое» становится очевидной. Второе — переучи себя на staggered timing: когда панель выезжает на экран, её иконка и текст должны прилетать не одновременно с фоном, а с задержкой 100–200 мс. Этот один приём — следствие диснеевского принципа follow-through (продолжение движения) — отличает дефолтные браузерные ease-in-out от того, что делает Rauno. Третье — не торопись брать библиотеку: научись сначала собирать перетаскивание на голых Pointer Events с transform: translate3d (это включает GPU-ускорение и убирает дёрганья), и только потом подключай Motion ради springs и жестов.

И последнее — посмотри, на чём собран сам rauno.me: это Next.js на Pages Router, стили на Stitches (CSS-in-JS), а анимации — преимущественно ручные, на CSS-переменных и Web Animations API, без сторонних библиотек. Это важный сигнал для джуна: автор, который сделал имя на «бесшовных» анимациях, в своём портфолио обходится без Framer Motion. Сначала фундамент — Pointer Events, transform, requestAnimationFrame, CSS-переменные для таймингов, — и только потом инструменты поверх. Подписаться имеет смысл на его Twitter/X @raunofreiberg и GitHub raunofreiberg — он регулярно выкладывает короткие видеоразборы того, как именно собрана конкретная микроанимация.

Robin Mastromarino

Robin Mastromarino

Робен Мастромарино — креативный разработчик из Парижа, который специализируется на сайтах-аттракционах: длинных скролл-историях с тяжёлой графикой, живой типографикой и физикой инерции. Его персональный сайт собрал Site of the Day и Site of the Month на Awwwards, плюс награды от FWA и CSS Design Awards. На главной нет ни одного «обычного» блока — фоны, превью кейсов и переходы между страницами рендерятся в WebGL, а DOM играет роль тонкой надстройки, которая ловит клики и проксирует их в 3D-сцену.

Основной инструментарий — связка Three.js (а в части демок более лёгкая библиотека OGL) для рендера через WebGL и GSAP с плагином ScrollTrigger для тайминга. Часть проектов он делал вместе с креативным разработчиком Patrick Heng, отдельно работал над интерактивом для гейм-студии Quantic Dream и кампаний модных домов уровня Dior. Ключевой приём — кастомные шейдеры: шейдер это мини-программа, которую браузер отправляет в видеокарту, чтобы та посчитала цвет каждого пикселя. Готовые материалы Three.js умеют только в стандартное освещение, а собственный шейдер позволяет, например, «искривлять» картинку по скорости скролла или растягивать её краями, как мокрую ткань.

Поверх сцены ложится post-processing — пост-обработка кадра уже после того, как 3D отрисовалось. Это отдельный проход рендера, где готовый кадр пропускается через ещё один шейдер: добавляются хроматическая аберрация (RGB-каналы разъезжаются по краям, как у старой плёнки), bloom (свечение вокруг светлых участков), плёночный шум, искажения от mouse-pointer. Частицы и системы из мелких точек дорисовываются как instanced-меши: одна геометрия копируется тысячи раз на GPU за один вызов, иначе FPS просел бы до однозначных значений.

Главный учебный takeaway — режиссура скролл-нарратива через ScrollTrigger. Это не «появись когда долистал», а полноценный таймлайн: позиция скролла привязывается к прогрессу анимации числом от 0 до 1, и это число прокидывается как uniform-переменная (входной параметр) в шейдер. JS только тянет ползунок, а сам шейдер остаётся stateless — он не помнит, что было кадром раньше, и каждый кадр считает картинку с нуля по текущему прогрессу. Такой подход даёт обратимость: пролистал назад — анимация откатилась честно, без рассинхронов. Второй вывод: кастомные шейдеры нужны не ради понтов, а когда стандартные материалы упираются в потолок — нельзя через настройки MeshStandardMaterial сделать «волну, амплитуда которой зависит от скорости курсора», а через свой fragment shader — десять строк кода.

Третий вывод — мобильная версия у Мастромарино заметно проще десктопной, и это не лень, а архитектурное решение. На телефоне отключается часть post-processing-проходов, снижается разрешение рендер-таргета (внутреннего «холста», куда рисует видеокарта — его потом масштабируют до экрана), число частиц режется в разы, тяжёлые шейдеры заменяются на упрощённые. Детектится не только ширина экрана, но и поддержка WebGL2, число доступных текстурных слотов, флаг prefers-reduced-motion для тех, кому укачивает от параллакса. Для джуна это полезный шаблон: сначала задайте «бюджет кадра» (целевые 16 мс на кадр для 60 FPS), а потом режьте эффекты, пока в него не уложитесь, — а не наоборот.

Dejan Markovič

Dejan Markovič

Деян Маркович — продуктовый дизайнер из Марибора (Словения), у него за плечами больше десятка лет работы со стартапами и растущими командами: мобильные приложения, SaaS, маркетплейсы, внутренние инструменты. Сейчас он работает на себя как фрилансер и берёт отдельные проекты. На главной он коротко формулирует свой подход: великие продукты получаются не из «более красивого интерфейса», а из «более точных решений», — и именно это задаёт тон всему сайту.

Портфолио сделано как личный сайт-минимализм: никаких анимаций «вау», никаких полноэкранных видео в шапке. Внешне это статический сайт — лёгкая разметка HTML, скромная CSS-сетка, картинки кейсов в формате .webp для экономии трафика, никакого тяжёлого JS-фреймворка в кадре. Навигация — три пункта: Feed, Photos, About. Типографика держится на паре «акцидентный шрифт с засечками для заголовков + нейтральный гротеск для тела текста»: это и есть та самая дисциплина в два шрифта, которая делает страницу спокойной и читаемой без лишних украшений.

Кейсы у Деяна построены по одной и той же скелетной схеме: проблема, в которой жил продукт, процесс — что именно делалось и как принимались решения, результат — обычно с цифрами. Например, по приложению Days он прямо пишет: founding designer и product owner в команде из двух человек, вёл продукт от запуска до версии 2.0, итог — миллион с лишним загрузок, 12 тысяч отзывов со средней 4.8 и порядка трёх тысяч активных подписок. По работе в InVision — Senior product designer, продукты Design System Manager, Craft, Inspect, зона ответственности: продуктовая стратегия, UX-архитектура, масштабируемые дизайн-системы для связки «дизайн → инженеры». Заметь формулировки: не «делал красивое», а «какая была роль, какие продукты, какие метрики».

Почему такой content-first портфель работает на найм лучше, чем сайт со спецэффектами. Когда тебя нанимают, нанимающему нужно за пять минут понять три вещи: какие задачи ты решал, что именно делал лично ты (а не «мы командой»), и что в итоге изменилось у пользователей или у бизнеса. Анимации, кастомные курсоры и параллакс на эти три вопроса не отвечают — наоборот, они шумят и мешают увидеть мышление. Аккуратная вёрстка, спокойная типографика и кейсы с цифрами читаются быстро и убедительно: видно структуру мышления, а не уровень владения GSAP.

Что отсюда полезно унести джуну. Первое — структурируй каждый кейс по схеме «проблема → процесс → результат» и не ленись добавить хотя бы одну метрику в финал (загрузки, время на задачу, конверсия, NPS — что угодно измеримое). Второе — дисциплина типографики: ограничь себя двумя шрифтами на весь сайт, например один с засечками для h1/h2 и один гротеск для body, и заведи строгую шкалу размеров — это даёт «дизайнерский» вид без единого декоративного элемента. Третье — научись описывать свою роль так, чтобы было понятно, что делал именно ты: вместо «работал над приложением» — «отвечал за онбординг, переписал три экрана, конверсия из установки в первое действие выросла с 38% до 51%». Эта формулировка одинаково работает и для дизайнера, и для фронтендера в резюме.

Gopal Oswal

Gopal Oswal

Гопал Освал — студент из Индора (Индия), учится в IIPS DAVV на программе BTech + MTech по информационным технологиям, параллельно подрабатывает SDE-интерном в Zomato и активно решает задачи на CodeChef и LeetCode. Его портфолио демонстративно собрано на ваниле: ни React, ни Vue, ни сборщиков — три отдельных HTML-файла index.html, cli.html и 3D.html, склеенных через jQuery, Bootstrap, AOS (анимация при скролле) и плагин typewriter-effect для эффекта печатающейся машинки в шапке. Для джуна это полезный референс — видно, что портфолио-визитку не обязательно тащить на полноценный SPA-фреймворк.

Главная фишка — три режима отображения одного и того же резюме. «Обычный» режим — это классический лендинг с секциями about / skills / projects, собранный на сетке Bootstrap. CLI-режим открывает чёрный экран с псевдо-терминалом: вы вводите команды вроде about, skills, projects — и парсер на чистом JS выводит ответ строкой. 3D-режим запускает Three.js — это WebGL-библиотека для трёхмерной графики в браузере — и помещает вас от первого лица в виртуальный «парк», по которому можно ходить мышью и клавиатурой через PointerLockControls; стенды-таблички в этом парке и есть разделы портфолио.

Живые цифры по GitHub подтягиваются простым приёмом, который удобно повторить и в своих проектах: вместо самописных запросов автор подставляет картинки-виджеты с сервиса github-readme-stats.vercel.app — это бесплатный прокси, который сам ходит в GitHub REST API (REST API — способ общения клиент/сервер по HTTP, где данные приходят в формате JSON), рисует SVG-карточку со звёздами и языками и отдаёт её как обычное изображение. Карточки рейтинга по LeetCode и CodeChef в исходниках не встроены как виджеты, в текущей версии это просто ссылки на профили — есть куда дотянуть форк. Сам сайт открыт: репозиторий oswalgopal/oswalgopal.github.io лежит на GitHub публично, можно клонировать и разбирать.

Что отсюда забрать в свою копилку. Во-первых, переключатель режимов реализован максимально приземлённо — без state-менеджмента (state — состояние компонента, то, что определяет, как он отрисуется прямо сейчас) и без роутера: иконки в шапке ведут href-ами на разные HTML-страницы, каждая со своим набором скриптов. Это плюс по скорости загрузки (3D-движок не тянется, если вы открыли обычный режим) и минус по DRY — секции «обо мне» дублируются в трёх местах, и при правке нужно синхронно менять каждую. Во-вторых, GitHub-карточки картинкой — самый дешёвый способ показать актуальные данные без бэкенда и без CORS-плясок (CORS — браузерная политика, которая ограничивает запросы между разными доменами).

И главное наблюдение — про границу разумного. Mode-switcher оправдан, когда каждый режим показывает что-то принципиально разное и решает задачу: CLI-версия — это демо умения работать с парсером команд и DOM, 3D-версия — демо знания Three.js, обычная — собственно резюме для рекрутёра, который пришёл на десять секунд. Если же все три режима просто перерисовывают один и тот же список навыков разным шрифтом — это уже over-engineering: лишний код, лишние баги, лишний вес. Юниору на старте полезнее сделать один аккуратный обычный режим и одну живую интерактивную демку рядом, чем три неподдерживаемых клона.

Что брать в своё портфолио

Если выписать общие приёмы по всем десяти сайтам, получится короткий чек-лист — рабочий набор для своего портфолио вне зависимости от того, делаешь ли ты «вау-аттракцион» или строгий минимализм.

  • Покажи роль, а не процесс. Не «работал над приложением» — а «отвечал за онбординг, переписал три экрана, конверсия из установки в первое действие выросла с 38% до 51%». Эта формулировка одинаково работает и для дизайнера у Деяна Марковича, и для фронтендера в резюме.
  • Каждый кейс — по схеме проблема → процесс → результат с цифрой. Не «сделали красивый интерфейс» — а «было N, сделали M, изменилось так-то». Если измеримой метрики нет, опиши хотя бы рамки — сколько людей, сколько экранов, какие ограничения.
  • Дисциплина типографики. Один-два шрифта на весь сайт, строгая шкала размеров, line-height не меньше 1.5 для абзацев. У Бриттани Чанг и Деяна Марковича «дизайнерский» вид собирается именно за счёт этого, а не за счёт декора.
  • Доступность с первого дня. Skip-link, понятные focus-стили, поддержка prefers-reduced-motion, семантические <section> и <main> вместо моря <div>. Это та самая категория навыков, которая отличает «верстаю по макету» от «понимаю платформу».
  • Не тяни фреймворк, если хватает CSS. У Линн Фишер весь сайт собран без JS-фреймворков; у Гопала Освала — три HTML-файла на ванили; даже Рауно Фрейберг, поднявший имя на бесшовных анимациях, в своём портфолио обходится без Framer Motion. Сначала фундамент (Pointer Events, transform, requestAnimationFrame, CSS-переменные), потом библиотеки.
  • Открой исходник. Если есть возможность — выложи репо на GitHub. Это сразу превращает портфолио из «вот сайт» в «вот сайт + я могу обсудить любое решение по коду». Шаблон bchiang7/v4 разлетелся на 8 тысяч звёзд именно благодаря тому, что Бриттани разрешила форки.
  • Бери одну запоминающуюся фишку. Машинка у Бруно Симона, Windows XP у Хеффернана, ежегодный редизайн у Линн Фишер, accessibility-first у Бриттани, content-first у Деяна. Одна точная идея, которую сайт хорошо реализует, лучше пяти приёмов «как у всех».
  • Подумай про мобилу с самого начала. Робин Мастромарино отключает на телефонах половину post-processing-эффектов; Хеффернан переключается на упрощённый 2D-режим. Не делай тяжёлый WebGL-сайт, который на iPhone лагает — иначе половина рекрутёров не увидит вообще ничего.

Проголосуй за портфолио, которое тебе больше всего понравилось

Если хочется не просто посмотреть, а сделать — самый короткий путь такой: выбери из этого списка одно портфолио, чья эстетика тебе ближе всего, открой исходник или DevTools и попробуй воспроизвести один конкретный приём (плавный скролл, скролл-анимация, типографическую шкалу, accessibility-паттерн). Получишь живой кейс с честным «было/стало» — и его уже можно класть в своё портфолио первым проектом. А там и до второго недалеко.