14544
Блог Lead JS-разработчика из Хельсинки Автор: @bekharsky По рекламе: https://telega.in/channels/htmlshit/card?r=GLOiHluU или https://t.me/it_adv Чат: https://t.me/htmlshitchat
#статья дня
Надо было эту статью на фишки раздербанить, ну да ладно. Итак, задача: сделать сетку, элементы которой должны иметь четкое и, возможно, изменяемое соотношение сторон.
Передавать соотношение сторон можно через классы, конечно, но мы в 2024 году, так что будем использовать CSS-переменные (`--ratio: 4/3`). Дальше имеются два варианта:
1. Задать соотношение сторон всей строке через, удивительное рядом, складывание дробей: 4/3 + 2/3 = 6/3. Сразу можно понять, что минусов у решения достаточно.
2. flex-grow. Легко и просто.
Подробнее о решениях и ходе мысли в статье:
https://9elements.com/blog/building-a-combined-css-aspect-ratio-grid/
Флексы рулят, котаны :)
#css #grid #flex #бородач
#инструмент дня
И снова на связи Глеб, автор extended-fetch. Слово автору.
Недавно потребовалось проанализировать зависимости в проекте (была проблема с транзитивными) и искал удобный инструмент для визуализации дерева зависимостей.
В итоге нашел https://npmgraph.js.org/
Что дает инструмент:
- анализ пакета из репозитория npm
- анализ package.json
- отображение интерактивного графа зависимостей (самое вкусное)
- выделение цветом заивисимостей по степени актуальности / по типу модуля (esm/cjs) / по числу мэйнтейнеров
- для выбранного модуля доступен детальный отчет по клику (на скриншоте пример)
Всем деревьев зависимостей, котаны!
Напоминаю, что кто угодно может выкатить пост на канал, если есть чем поделиться. Не стесняйтесь!
#node #dependencies
🔥Работаете программистом на аутсорсе за рубежом, но языковой барьер мешает развитию?
— Устали от однообразных учебников и курсов без результата?
Хватит тратить время впустую!
Переходите в канал Mr Grega | English FAST и постигните реально работающий технический английский.
Уже после 10 занятий вы будете свободно понимать требования заказчиков и коллег-программистов.
А еще через 5 занятий научитесь грамотно объяснять сложные профессиональные вопросы, вести дискуссии и презентации.
При этом вам не нужно тратить годы на изучение языка с нуля. Всего 10% ключевых знаний дадут вам 90% результата.
Эти инсайты технического английского не раскроет ни один учебник или курс.
Перестаньте топтаться на месте в карьере из-за незнания языка.
Присоединяйтесь к каналу /channel/+RVpd1URyKb1iYmM6 и постигните секреты эффективного технического английского уже сегодня.
#заметка дня
А как вы, котаны, боретесь с багами?
Даже не так. Как боретесь — понятно, пишете код. Но каков процесс?
Мы вот у себя пытаемся играть в Zero Bug Policy. Это не значит, что в продукте нет багов и никогда их больше не будет. Это значит, что ни один баг не должен оставаться незамеченным или проигнорированным. По каждому обязательно принимается решение.
1. Баг в продакшене:
Создаётся user story (здесь и далее сторя). Отправляемся чинить или писать статью о том, почему это не баг.
2. Баг найден в процессе функционального тестирования
Должно быть принято решение:
a) Если он мешает процессу и блокирует релиз — немедленно создаётся сторя и баг уходит в работу
б) Если процессу работы не мешает и релиз уйдёт как есть — обновляем описание основной стори. Ни стори ни подзадачи не создаётся.
3. Примерно то же самое происходит если баг найден в процессе регресс-тестирования:
Либо создаётся задача и чинится, либо не создаётся ничего, если мы удовлетворены обходными путями или наличием технической документации по этому поводу.
Всплытие багов в регресс-тестировании означает, что имеются большие пробелы функциональном тестировании или даже планировании.
Мы раз в две недели проводим Bug Busting встречу на которой баги распределяются по категориям или закрываются как неактуальные. Наличие багов в бэклоге означает, что процесс сломан или баги не столь важны.
Да, может показаться, что мы просто заметаем проблемы под ковёр — но это не так.
Во-первых, наличие багов в бэклоге портит планирование, что в свою очередь портит настроение разработчикам.
Во-вторых, мы можем быть уверен, что баг от саппорта как минимум прочитал кто-то кроме, собственно, человека его создавшего.
В-третьих, ничто не вечно под луной. Сегодня ты тратишь три дня на баг, влияющий на мелкого пользователя, а завтра вся фича переписывается или выкидывается.
А у вас чо как?
#dev #process #bugs
#статья дня
Злые Марсиане выпускают крутейшие статьи с завидной регулярностью. Вот очередная: https://evilmartians.com/chronicles/html-best-practices-for-login-and-signup-forms
На сей раз — про ошибки при разработке форм. И их, согласно статье, 11. Давайте кратко пробежимся.
1. Ставь autocomplete в нужное положение (username, current-password etc.).
Мы тут, кстати, обсуждали возможные значения и даже проблемы.
2. type="email", тут всё ясно.
3. Интерактивные элементы должны быть кнопками или ссылками, а не дивами (и ведь находятся же).
4. Не забывай про существование тега form (и такие тоже существуют).
5. Не используй placeholder как label.
6. Помни о label, особенно для галочек.
7. Состояние :focus должно быть визуально подтверждено.
8. Маркируй невидимые поля для скринридеров.
9. Не прерывай ввод внезапной валидацией (бесит).
10. Исключи случайную повторную отправку формы.
11. Помни о сетевых задержках.
В статье полно примеров и объяснений. Проверяйте свои формы, котаны.
#form #ux #бородач
Хотели бы начать работать в иностранной компании, но не уверены, что вы сможете пройти интервью на английском?
В этом поможет Игорь - опытный преподаватель с более чем 5-летним стажем! Он помог более 40 студентам подготовиться к интервью, конференциям, а также переехать в другую страну.
Посты на его канале заменят годы обучения у репетиторов:
- Как подготовиться к интервью на английском?
- Что нужно, чтобы выучить английский язык?
- Какие правила необходимо знать, чтобы объяснить любую мысль на английском?
- Как сэкономить $30,000 благодаря английскому?
Подписывайтесь и изучайте английский!
#заметка дня
Есть такой элемент — template. Название говорит само за себя: это шаблон.
Пишете в него некий HTML/SVG код, потом клонируете и вставляете куда вам надо.
На этом месте апологеты фреймворков ухмыльнулись, но вы же не одни на свете, да?
const content = template.content. firstElementChild.cloneNode(true);
div или — привет из прошлого — script type="text/template"?dd храните там, хоть tdtemplate и точно не индексируют. А с div hidden всё не так однозначно.
#новость дня
Итак, мы писали Джаваскрипт в браузере, в консоли, на серверах, на микроконтроллерах, в играх, в кофеварках, в аудиоплеерах, телевизорах, в макросах офисных пакетов, в NoSQL базах данных...
Но до сих пор не писали его в хранимых процедурах MySQL!
Итак, встречайте: JavaScript Stored Programs in MySQL. И соответствующий пост в блоге Oracle: https://blogs.oracle.com/mysql/post/introducing-javascript-support-in-mysql
Зачем? Ну для разных целей:
1. Извлечение данных, очевидно
2. Форматирование
3. Примерный поиск
4. Валидация данных
5. Собственные алгоритмы сжатия, сериализации и десериализации данных
Пример:
CREATE FUNCTION gcd_js (a INT, b INT) RETURNS INT
LANGUAGE JAVASCRIPT AS $$
let [x, y] = [Math.abs(a), Math.abs(b)];
while(y) [x, y] = [y, x % y];
return x;
$$;
Котаны, мечтаете об айти-карьере за границей? Тогда обязательно стоит узнать о визе цифрового кочевника в Испании! 👨💻
🌐 Виза цифрового кочевника предоставляет уникальную возможность фрилансерам и удаленным сотрудникам освоить Испанию и получить вид на жительство после 5 лет пребывания!
🚀 Быстрое оформление, переезд с семьей и официальный статус пребывания делают испанскую визу наилучшим выбором для тех, кто стремится к новым горизонтам!
📈 Получайте свежие обновления и полезные советы о релокации в канале миграционного центра Mircare.
🔗 Ищете лайфхаки и подробные инструкции по каждому этапу? Так они прямо здесь — /channel/+6rQlKo-canRlNDc6
ООО «НД Коммерц Групп» ИНН: 7713410700 erid: 2SDnjcirWNL
#фишка дня
Даже две, но об одном и том же: как сделать "альбомный" бэкдроп у картинки.
Что такое бэкдроп? Это фон, который полностью зависит от контента, например, заливается усредненным цветом. Вы наверняка видели похожие эффекты в разных аудиоплеерах, отсюда и название — альбомный. Да и на ютубе раньше было модно заполнять края у вертикальных видео тем же размытым видео.
Итак, два варианта.
1. От Артура Бьена. Надо предупредить, он немного упоротый:
а) заполняем фон контейнера однопиксельными копиями картинки:
background-image: url(var(--bg));
background-size: 1px 1px;
background-repeat: repeat;
div::after {
--backdrop: invert(0.2) contrast(0.8) saturate(1.7) blur(8px);
backdrop-filter: var(--backdrop);
}
mix-blend-mode: overlay;
div: before {
content:"";
border- image:
var (--img) 2/
calc(50% - var (--w)/2 + var (--b)) /
calc (1.5*var(--b));
filter: contrast(.8) blur(var(--b));
}
#инструмент дня
Раз уж упомянули пару постов назад Кори Хауса, то давайте ещё чего-нибудь по его рекомендации.
И сегодня это инструмент для поиска дубликатов кода: jscpd.
Сразу ссылка на GitHub: https://github.com/kucherenko/jscpd
Как получаются дубликаты, клоны кода? Да от плохих абстракций. Сами по себе они ничем не плохи, ну есть у вас повторы там-сям, кому от этого плохо?
Ну, пока лежат — никому. Но если в одном таком куске кода баг — это лишь вопрос времени, когда он себя проявит в другим таком же куске. А чинить-то его везде надо.
Ну и на фронтенде банально раздувается размер бандла. Тоже такое себе.
Вообще, клонированный код это показатель того, что где-то у вас плохо с абстракциями, одна и та же логика применяется к, казалось бы, разным сущностям и так далее. Само по себе, это не так плохо, не просто же так в оппозиции к DRY (do not repeat yourself) существует WET (write everything twice).
Но иметь инструмент для поиска совсем уж лишнего — весьма неплохо.
А для тех, кому надо докопаться до сути, имеется целое исследование по поиску клонов кода, на 115 страниц: https://research.cs.queensu.ca/TechReports/Reports/2007-541.pdf
Но все, что я могу сказать — это что jscpd является реализацией детектора копий первого типа 🫠
Пользуется кто-нибудь чем-то подобным в своих проектах? Делитесь.
#js #clone #lint
Cloud Native DIY — бесплатный практический тьюториал от VK Cloud
В программе — все базовые знания по работе с современными облачными платформами на примере VK Cloud. Вы изучаете теорию и сразу же применяете ее на практике, выполняя домашние задания на платформе.
Что входит в Cloud Native DIY
✅ 20+ видеолекций от практикующих экспертов — инженеров и архитекторов облачной платформы.
✅ 3000 бонусных рублей каждому новому пользователю облачной платформы для выполнения практических заданий.
✅ Доступ к чат-боту с дополнительными видео и статьями, которых нет в открытом доступе.
✅ Сертификат о повышении квалификации после выполнения всех практических заданий.
Зарегистрироваться на курс: https://bit.ly/4b0R9ad
#баг дня
Дисклеймер: возможно, кто-то мне снова напишет, что стыдно таким делиться. Как правило, это характеризует людей, далёких как от разработки, так и от сути ведения блогов и каналов.
Преамбула
Некий сервис, назовём его Doodle Lampolytics, заставил всех своих клиентов переползти с модели подсчёта просмотров страниц на модель подсчёта событий.
Суть проблемы Doodle очевидна: постраничная модель слабо подходила для серьёзной аналитики данных в веб-приложениях. Даже элементарные лендинги стали гораздо сложнее, чем просто переходы по ссылкам.
И если раньше мы в нагрузку к «просмотру» передавали так называемые индивидуальные размерности и метрики, привязанные к сессии, то теперь — каждое событие могло нести индивидуальный их набор.
Не в последнюю очередь это связано с ужесточением запретов на слежку за посетителями сайтов.
Поскольку в типичном проекте зачастую присутствует не одна сотня событий/страниц, то переезд сопровождается знатным перетряхиванием всей аналитики проекта.
Суть
Суд да дело, приходим мы к идее передачи события с неком контекстом:
trackEvent('event_name', context) {}
{
productId,
optionId,
orderId,
locale,
}
product_id,
product_ıd
option_id,
option_ıd
const lowercase = (input = '', options) => input.toLocaleLowerCase(options?.locale);
Всем привет! 17 февраля в Питере пройдет первый DUMP Spb — масштабная IT-конференция для разработчиков и IT-менеджеров.
В программе — 32 доклада в 4 треках: Backend, Frontend, Testing&QA и Management. Уровень докладов — middle+. Будет очень много нетворкинга, общения со спикерами, движухи на стендах партнеров и теплая неформальная афтепати.
Вы сможете остановиться на каком-то одном треке или перемещаться из зала в зал, чтобы послушать самые интересные доклады. Вся программа конфы тут.
Что еще:
- Активный нетворкинг,
- Общение со спикерами и участниками конференции,
- Движухи на стендах партнеров,
- Большая афтепати,
- Горячий обед и кофе-брейки,
- Мерч, фотограф, записи докладов после конференции
По промокоду РАЗРАБОТЧИК скидка 10% на билеты.
#детектив дня
Сегодня в чат пришёл подписчик с забавной проблемой.
Дано: форма с двумя полями, одно просто как HTML-тег, второе — React-компонент. Ну, очевидно, компонент тоже содержит поле ввода.
При нажатию на клавишу Ввод событие onSubmit не происходит, форма не отправляется. Хотя, вроде как, всем известно, что это — стандартное поведение.
Было замечено, что при удалении React-компонента всё отлично работает. И первым предположением стало, что React что-то испортил, или песочница кривая.
Кто-то догадался сделать ванильный пример, поведение сохранилось.
То есть, вот такое:
<form onSubmit="alert('aha')">
<input type="text"/>
<input type="text"/>
</form>
<input type="submit" hidden/>
Любишь читать техно-новости, но в каждом канале не посты, а одна вода? 💧
Тогда тебе точно понравится новый канал от двух программистов (Питон, если кому интересно 🙂). Они выпускают новости в кратком, легко-четаемом формате.
Подписывайся, чтобы раньше всех узнавать все самое главное, при этом не загружая голову лишними эпитетами 👌
Перейти в канал 📝
#такое дня
Давайте немного о жизни офисных крыс. Пятница, вечер. Почему бы и нет.
Как правило, я хожу ежедневно в офис, потому что мне не нравится работать из дома.
Точнее, не так. Я работал из дома 10 лет, надоело.
Но суть не в этом. В офисе, конечно же, есть кофемашины. Два автомата, наливающих фильтр-кофе, и две капсульные, Nespresso Vertuoline.
Офис-менеджер регулярно закупает новые капсулы, от эспрессо на 40 мл, до американо на 230 и тыквенного мексиканского на 350. Я предпочитаю делать капучино на эспрессо по утрам, но многие не парятся и просто берут капсулы на объём побольше.
Но что-то пошло не так и заказаны были только эспрессо и двойные эспрессо (40 и 80 мл). Любители американо и всякой отравы взвыли. Никто не хотел греть чайник, чтобы разбавить 80 до 230.
Надо было что-то делать, помимо срача в Slack.
Объём кофе абсолютно одинаковый, что в капсуле для эспрессо на 40, что на 230 мл. Отличаются лишь давление и объём воды.
При всём при этом, если пропустить одну капсулу дважды — получается ерунда.
Так вот, в кофемашинах Nespresso давление (точнее, капсула быстро раскручивается, чтобы это давление создать) и объём воды кодируются штрих-кодом на крышке капсулы.
Дело за малым — взломать штрих-код и подменить его на капсуле.
Взламывать, конечно, никто ничего не собирался.
Ведь есть Reddit, на котором была выложена статья с описанием структуры штрих-кода:
01111010010001001000010110100111100101000100100001011010011110010100100010001001101010111010010010001000010110101011100101000100100010011010
#такое дня
Ну что, котаны. Это случилось. Figma стала просить денег за DevMode.
Если вы жили последние месяцев 8 под камнем, то Figma перенесла специфичные для разработчиков фишечки в отдельный режим. Теперь режимы редактирования, просмотра и экспорта в код разнесены практически насовсем.
Что такое DevMode и какие преимущества он давал? Ну и даёт, для тех, кто платит.
1. Автоматическое отображение отступов и применённого лейаута прямо на холсте
2. Инспекция боксовой модели контейнеров
3. Автогенерация кода (CSS, iOS Swift/SwidtUI, Android Java/Kotlin и через плагины ещё с десяток платформ, включая Flutter)
4. Автоматическая генерация дизайн-токенов для выбранной платформы.
5. Сравнение версий дизайна
6. Именование слоёв
7. Более удобный экспорт ассетов и контента.
Что меня бесит больше всего, что Figma буквально пробила свой путь в наши сердца отображая CSS и отступы на холсте по-умолчанию. А теперь сделала такую себе кодогенерацию и хочет денег. Если ты учишься, это малость неудобно. Если зарабатываешь на фигме деньги — ну окей, возможно, стоит и заплатить.
Впрочем, для базовой работы DevMode может оказаться и не нужен.
1. Отступы на холсте всё так же отображаются по зажатой клавише Option/Alt.
2. Настройки эффектов никто не скрывал, они легко считываются.
3. Для сложных случаев, как минимум, в вебе, всегда можно установить расширение. Например, Inspect Styles (на скрине). Оно вернёт на место как CSS-переменные (из токенов), так и все нужные правила.
Напоминаю, что бездумно копировать отступы и координаты из генератора кода в Figma не надо. Вёрстка не про это. А вот настройки шрифта, фона и эффектов — да, очень уютно.
Делитесь вашими любимыми плагинами в комментариях, котаны!
А вообще, не забывайте о Pixso и PenPot! PenPot ещё и опенсорсный, можно у себя развернуть.
#figma #design #greed #money
Живу обычной жизнью, как все. Питаюсь разнообразно, тренируюсь в кайф, отмечаю дни рождения, периодически могу выпить алкоголь и при этом я круглый год в форме 💪🏻
Сделать себе крутую форму и убрать живот может каждый IT-спец, если найдет свой способ по питанию!
Самое главное, чтобы питание вписывалось в твой текущий образ жизни - и вуаля, ты круглый год в прекрасной форме!
Нет проблем с ЖКТ, в зеркале ты видишь спортивное тело и кайфуешь. А продуктивность выходит на новый уровень и
25-ый час в сутках.
Хочешь научиться также выстроить весь процесс в кайф и при этом терять на весах каждый месяц 3-6 кг?
➡️ На моем канале ты узнаешь:
⁃ Метод, который позволяет перестать поджирать 🥐
⁃ Как убрать живот, даже если совсем не до этого?
⁃ Как похудеть разработчику, не считая калории?
Жду тебя, подписывайся и будь как дома 👉 /channel/+1iL4KnO5R8s2YjYy 👈
Реклама. Милютин Николай Николаевич. ИНН: 741524869725. Erid: 2Vtzqw4uU8o
#число дня
В дружественном чате прошло очередное ежеквартальное обсуждение разрешений макетов и экранов.
Я не буду пока репостить свои статьи на тему, лишь задам вопрос.
Кто догадается, что такое 1536x864 на этой годовой статистике разрешений экранов мониторов?
Между прочим, 11% дисплеев.
https://gs.statcounter.com/screen-resolution-stats/desktop/worldwide
При встрече угощу кофе того, кто догадается первым.
Ну или кого вообще встречу.
#css #resolution
#тип дня
Кричащий банан 🍌 (да-да) принёс шикарную фишку TypeScript: как типизировать ключ объекта без каста.
Решение: заранее объявите тип переменной перебора как keyof typeof. Всё, вы великолепны.
Пруф на TS Playground.
#typescript #cast #бородач
Да кому ты там нужен?
Ой, начинается, в Европу нужен капитал на переезд…
#фишка дня
Стопудово вы делали эффекты как на видео через три div-а или span-а. Ну просто потому что трансформации на SVG это абсолютная боль.
Типа такого: https://codepen.io/alinaki/pen/abXpvyQ
Да, пример очень простой, но даже это на SVG бывает проблемно санимировать.
Хотя, казалось бы, для этого и предназначено.
А вся проблема в том, что для SVG определение координат для преобразований происходит немного иначе, нежели чем для элементов. Выходов из ситуации есть несколько.
Первый, от Аны Тюдор: исправить viewBox, поставив вместо 0, 0 (левый верхний угол) — -width/2,-height/2, соответственно, исправив остальные координаты.
Второй, интереснее, от Джея: указать следующие правила в CSS:
transform-box: fill-box;
transform-origin: 50% 50%;
#статья дня
На связи опять стилизация скроллбаров. Мы только недавно обсудили, как избежать некоторых связанных с этим багов в Safari, как подоспел Chrome 121 с интересным обновлением.
И что он нам принёс? Вы не поверите, поддержу стандартных правил scrollbar-width и scrollbar-color.
В Firefox они с 2018 года, а Chrome всё это время использовал правила от WebKit. Впрочем, все пользовались и было пофигу.
Пример:
.scroller {
--scrollbar-color-thumb: hotpink;
--scrollbar-color-track: blue;
--scrollbar-width: thin;
--scrollbar-width-legacy: 10px;
}
/* Modern browsers with `scrollbar-*` support */
@supports (scrollbar-width: auto) {
.scroller {
scrollbar-color: var(--scrollbar-color-thumb) var(--scrollbar-color-track);
scrollbar-width: var(--scrollbar-width);
}
}
В «Аптечной сети 36,6» выросла скорость загрузки приложений после миграции ИТ-ландшафта в облако
«Аптечная сеть 36,6» продает товары для здоровья через сайты и мобильное приложение. Компания столкнулась с проблемой: старая ИТ-инфраструктура перестала отвечать ее растущим потребностям.
Чтобы улучшить пользовательский опыт, повысить управляемость и безопасность инфраструктуры, приложение для электронной торговли перенесли в облако VK Cloud. Вот какие результаты компания получила:
🔹Сайты и мобильное приложение работают быстрее — загрузка страниц сократилась с 1 до 0,67 секунды.
🔹Уменьшились затраты на построение инфраструктуры: развертывание обошлось на 35% дешевле, чем предыдущее.
🔹Компания соблюдает ФЗ-152 «О персональных данных».
Облако помогает улучшить работу любых интернет-магазинов и маркетплейсов. Вы можете перенести в облако готовый сайт или разработать его с нуля, используя готовые сервисы.
Узнайте о возможностях VK Cloud для интернет-магазинов
#такое дня
Решил принести вам на ночь. В 2013 году в официальной документации React предлагалось использовать jQuery для AJAX-запросов, а в качестве mock-сервера использовать встроенный в Python HTTP-сервер.
Правда, я, помню, использовал для таких задач сервер, встроенный в PHP... ну кто что умел.
С тех пор прошло 10 лет. Где мы теперь, котаны? :)
#заметка дня
Иногда полезно спорить с мэтрами по поводу разных штук. Не стоит всё подряд принимать на веру.
Вот, например, Кори Хаус, весьма известный консультант по React, предложил буквально следующее: чтобы не запутаться в бесконечных хуках useEffect в React, вместо неименованной функции передавайте именованную.
То бишь, вместо:
useEffect(() => {
// do stuff
}, [...deps]);
useEffect(function doSomething() {
// do stuff
}, [...deps]);
function useDoSomething(deps) {
useEffect(() => {
// some effect
}, [...deps]);
}
#такое дня
Уже довольно поздно. Отметьтесь реакциями, кто ещё онлайн.
Наберём достаточное количество — скину историю смешного бага, который у нас недавно произошёл по невнимательности.
Не наберём — скину её утром. Никуда она не денется.
Upd. Хорошо разогнались. Сейчас всё будет.
#фишка дня
Как легко и быстро добиться эффекта фаски на кнопке без использования вложенных и псевдоэлементов?
Конечно же, использовать градиентный бордер!
— Ну да, конечно, это кто делает градиентные границы без вложенных элементов?
Ну как, кто. Мы и делаем. Всё довольно просто:
border: 0.5vw solid transparent;
background: linear-gradient(#17181c, #17181c) padding-box, linear-gradient(to right, #1e1e22, #121316, #1e1e22) border-box;
🖼️📤🖼️📤🖼️📤🖼️📤🖼️📤🖼️📤🖼️📤🖼️📤🖼️📤🖼️
Ошибка 78% фронтендеров — часами искать макеты
Кто поумнее, тот уже давно подписался на культовый канал для поиска — Макеты для вёрстки.
Админ этого канала уже давно экономит время и нервы тысячам разработчиков.
Короче, если хотите быстро собрать себе крутое портфолио, подписывайтесь: тыык