WebDev+ | Веб-разработка
8.32K subscribers
505 photos
241 videos
10 files
700 links
Присоединяйтесь к нашему каналу и погрузитесь в мир веб-разработки

Связь: @devmangx
Download Telegram
HTML-совет

Тег <abbr> используют, чтобы пометить аббревиатуру или акроним (сокращение) от фразы или длинного слова.

Он улучшает доступность и понимание: можно дать расшифровку, которая появится при наведении.

Обычно <abbr> используют вместе с атрибутом title. Значение title показывается как подсказка, когда пользователь наводит курсор на содержимое <abbr>.

В этом примере:

WWW это сокращение от World Wide Web.
Когда пользователь наведёт на WWW, появится тултип с полной расшифровкой World Wide Web.

Зачем использовать <abbr>?

Доступность: скринридеры могут озвучивать полную форму, когда пользователь фокусируется на сокращении. Это помогает людям с нарушениями зрения.
Удобство: пользователь быстро видит смысл термина, не уходя со страницы и не ломая поток чтения.

@WebDev_Plus
👍2
Laravel Tip

Найди запросы, которые выполняются слишком долго. Это легко логировать с помощью:

@WebDev_Plus
SSR vs CSR vs SSG

Представь собес по вебу. Тебя спрашивают: в чем разница между SSR, CSR и SSG?

Это три стратегии рендера UI. Если выбрать не ту, можно легко просесть по скорости и SEO.

▪️SSR (Server Side Rendering)

Пользователь запрашивает страницу, сервер подтягивает данные, собирает HTML, подключает стили и отдаёт уже готовую разметку в браузер. Потом на клиенте подгружается JS и “оживляет” страницу, это называется hydration.

Плюсы:

▪️Хорошее SEO
▪️Контент появляется быстрее

Минусы:

▪️Интерактивность не мгновенная, пока hydration не отработает

Лучше всего для:

▪️блоги, новости, e-commerce
▪️всё, где важны SEO и свежие данные

CSR (Client Side Rendering)

Пользователь запрашивает страницу, сервер отдаёт пустой HTML плюс ссылки на JS/CSS. Дальше браузер загружает бандлы, JS строит страницу и накатывает стили.

Плюсы:

▪️После загрузки супер-интерактивно

Минусы:

▪️Плохое SEO (до выполнения JS страница фактически пустая)
▪️Медленный first paint/первый контент, особенно на слабых устройствах

Лучше всего для:

▪️дашборды, SaaS, внутренние панели
▪️всё за логином, где SEO не важно

SSG (Static Site Generation)

HTML генерируется заранее на этапе сборки/деплоя. Когда пользователь запрашивает страницу, сервер просто отдаёт готовый HTML файл. Никаких вычислений “на лету”.

Плюсы:

▪️Самый быстрый рендер
▪️Отличное SEO

Минусы:

▪️Плохо подходит для динамического контента или часто меняющихся данных

Лучше всего для:

▪️портфолио, документация, лендинги
▪️контент, который редко обновляется

В одну строку

▪️SSR: собирается на сервере на каждый запрос
▪️CSR: собирается в браузере после загрузки JS
▪️SSG: собирается при билде и отдается мгновенно

@WebDev_Plus
Please open Telegram to view this post
VIEW IN TELEGRAM
👍82
TypeScript сужает тебе выбор на основе того, что ты уже выбрал, и делает это по группам.

@WebDev_Plus
Как нормально организовать папки в коде?

Не важно, используешь ты React, Vue, Angular или просто TypeScript

3 самые типичные варианты ↓

@WebDev_Plus
This media is not supported in your browser
VIEW IN TELEGRAM
CSS-совет:

Используй логические свойства вроде margin-inline-start и text-align: start, чтобы верстка автоматически подстраивалась под любое направление письма.

@WebDev_Plus
This media is not supported in your browser
VIEW IN TELEGRAM
tabular-nums должно быть дефолтом для любых чисел, которые обновляются (таймеры, счетчики, цены, проценты, счёт, live-данные и т.д.).

Включить OpenType-фичу tnum можно через CSS-свойство font-variant-numeric.

.tabular-nums {
font-variant-numeric: tabular-nums;
}


@WebDev_Plus
👍1
Laravel Tip

Когда нужно обновить запись, но не трогать колонку updated_at, используй updateQuietly().

Без таймстампов. Без событий. Тихое, чистое обновление, когда оно реально нужно.

@WebDev_Plus
Если ты веб-разработчик и используешь ИИ, поставь это!

Agent Skills от Addy Osmani (Google) для:

* Web Performance
* best practices
* доступности (a11y)
* технического SEO

Под React, Vue, Angular или что угодно.

npx add-skill addyosmani/web-quality-skills


Вот какие skills поставятся:

* web-quality-audit - полный аудит в стиле Lighthouse
* performance - загрузка и оптимизация
* core-web-vitals - LCP, INP, CLS
* accessibility - WCAG и навигация с клавиатуры
* seo - meta-теги и структура
* best-practices - безопасность и стандарты

@WebDev_Plus
4
This media is not supported in your browser
VIEW IN TELEGRAM
autofill у инпутов по умолчанию выглядит стремно: эта заливка фона ломает аккуратные дизайн-системы, особенно в темной теме.

Пофиксил чисто CSS-хакам через inset-shadow:

autofill:shadow-[inset_0_0_0px_1000px_var(--color-background)]

Чтобы принудительно поставить нужный фон и убрать нативный синий.

https://micro.bossadizenith.me/writing/taming-chromes-autofill

@WebDev_Plus
👍4
Angular совет дня: твое приложение ходит в несколько API, но интерсепторы не могут понять, к какому из них относится запрос!?

Оберни. Отфильтруй. Готово

@WebDev_Plus
👍1
Это самый простой способ переключаться между режимами Dark, Light и System.

Просто добавьте элемент с выбранным режимом data-theme или удалите его из DOM, чтобы переключиться на System mode.

Может, это и не идеальный вариант, но это самый быстрый и простой способ!

@WebDev_Plus
Модалки бесят.

Хочешь, чтобы они бесили чуть меньше?

Используй overscroll-behavior: contain;

Что это делает:

Ты скроллишь модалку, доходишь до её конца и продолжаешь крутить дальше.

И тут бах, начинает скроллиться страница под ней. Модалка всё ещё открыта, но позиция на странице сзади уже уехала.

Это называется scroll chaining. Это свойство как раз это и останавливает.

Как это работает:

Когда пользователь доходит до конца прокручиваемого элемента, а модалки для этого вообще идеальный кейс, скролл просто останавливается. Он не продолжает передаваться родителю по цепочке.

На мобилках заодно не триггерит pull-to-refresh.

Где использовать:

• модалки и диалоги
• сайдбары и навигационные меню
• фиксированные контейнеры с overflow: scroll
• мобильные карусели

Поддержка браузеров: 95%

Одна строка CSS.

Модалки всё ещё бесят, но уже чуть меньше 😄

@WebDev_Plus
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
JavaScript использует лексическую область видимости.

Но знаешь ли ты, что такое lexical scope?

Лексическая область видимости означает, что область видимости переменной определяется тем, где она написана в коде, а не тем, откуда её вызвали.

Пример:

function outer() {
let x = 10;

function inner() {
console.log(x); // может обратиться к x из outer
}

inner();
}
outer();


Здесь inner() может получить доступ к x, потому что функция была объявлена внутри outer().

Это и есть lexical scope: функция как бы "помнит" окружение, в котором была создана.

Ключевые моменты:

* лексическая область видимости статическая, то есть фиксируется в момент определения кода
* внутренние функции могут обращаться к переменным из внешних областей видимости
* это фундамент, на котором в JavaScript построены closures

@WebDev_Plus
Хватит писать reduce() просто ради того, чтобы сгруппировать массив

Object.groupBy() уже работает во всех основных браузерах и позволяет группировать элементы массива по любому ключу в одну строку.

Чисто, читаемо, без зависимостей.

Подробнее 👇
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/groupBy

@WebDev_Plus
3👍2
Бывало такое, что sticky header перекрывает заголовки, на которые ведут якорные ссылки?

Простое решение: scroll-margin-top

Что это делает:

Добавляет дополнительный отступ сверху у заголовка.

Якорные ссылки продолжают работать, но заголовок оказывается ниже sticky header, так что хедер больше не перекрывает его часть.

Как использовать:

Если высота вашего хедера 80px, добавьте это к заголовкам:

scroll-margin-top: 80px;


Теперь, когда кто-то кликает по якорной ссылке, браузер прокручивает страницу до заголовка, но оставляет сверху 80px.

Заголовок отображается ниже хедера.

Дополнительный совет: если высота хедера меняется, например на мобильных устройствах, используйте CSS-переменные:

scroll-margin-top: var(--header-height);


Поддержка браузеров: около 96%

Одна строка CSS. И якорные ссылки наконец работают так, как этого ждут пользователи.

@WebDev_Plus
4
В JavaScript теперь есть немутабельные методы массивов

toSorted(), toReversed(), toSpliced() и with() возвращают новые массивы вместо того, чтобы изменять исходный.

Больше не нужно писать [...arr].sort(), чтобы избежать побочных эффектов.

Подробнее 👇
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toSorted

@WebDev_Plus
Please open Telegram to view this post
VIEW IN TELEGRAM
Нужно ли писать 5 media queries, чтобы шрифт выглядел нормально на разной ширине экрана?

На деле хватает одной строки CSS:

font-size: clamp(1rem, 2vw + 0.5rem, 2rem);


Как это работает:

Сразу задаются три значения: минимальный размер, предпочтительный (плавающий) размер и максимальный размер.

Браузер выбирает подходящее среднее значение, но при этом никогда не уходит ниже минимума и выше максимума.

Например:

* 1rem = минимум (16px). Текст никогда не станет меньше 16px.
* 2vw + 0.5rem = предпочтительный размер. Плавно масштабируется вместе с шириной вьюпорта.
* 2rem = максимум (32px). Текст не станет больше 32px даже на огромных мониторах.

Результат:

Текст масштабируется в зависимости от ширины экрана. Без breakpoints, без media queries. Просто плавная адаптивная типографика.

Где использовать:

* Заголовки, которым нужно масштабирование
* Основной текст в hero-секциях
* Любой текст, который должен подстраиваться под размер экрана

Поддержка в браузерах: около 95%

Одна функция.

И адаптивная типографика готова.

@WebDev_Plus
Laravel Tip

Хотите знать, как отработала ваша запланированная задача в полночь?

Тут вам повезло: вывод scheduled tasks можно без проблем сохранить или отправить по email

@WebDev_Plus
Создавать Promise с внешними resolve и reject стало чище 🧹

Promise.withResolvers() возвращает объект вида { promise, resolve, reject }

Больше не нужно заворачивать логику внутрь конструктора.

Подробнее тут
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers

@WebDev_Plus
Please open Telegram to view this post
VIEW IN TELEGRAM
3