Code Ready | Frontend
Авторский канал по Frontend разработке. Ресурсы, гайды, задачи, шпаргалки. Информация ежедневно пополняется! Cотрудничество: @energy_c РКН: https://clck.ru/3NJCKs
Показати більше📈 Аналітичний огляд Telegram-каналу Code Ready | Frontend
Канал Code Ready | Frontend (@code_ready) у мовному сегменті Російська є активним учасником. На даний момент спільнота об'єднує 21 557 підписників, посідаючи 6 157 місце в категорії Технології та додатки та 30 472 місце у регіоні Росія.
📊 Показники аудиторії та динаміка
З моменту свого створення невідомо, проект продемонстрував стрімке зростання, зібравши аудиторію у 21 557 підписників.
За останніми даними від 26 жовтня, 2026, канал демонструє стабільну активність. Хоча за останні 30 днів спостерігається зміна кількості учасників на -42, а за останні 24 години на -20, загальне охоплення залишається високим.
- Статус верифікації: Не верифікований
- Рівень залученості (ER): Середній показник залученості аудиторії становить 6.43%. Протягом перших 24 годин після публікації контент зазвичай збирає 4.29% реакцій від загальної кількості підписників.
- Охоплення публікацій: В середньому кожен допис отримує 1 386 переглядів. Протягом першої доби публікація в середньому набирає 925 переглядів.
- Реакції та взаємодія: Аудиторія активно підтримує контент: середня кількість реакцій на один пост – 23.
- Тематичні інтереси: Контент зосереджений навколо ключових тем, таких як css, браузер, интерфейс, загрузка, api.
📝 Опис та контентна політика
Автор описує ресурс як майданчик для висловлення суб'єктивної думки:
“Авторский канал по Frontend разработке.
Ресурсы, гайды, задачи, шпаргалки.
Информация ежедневно пополняется!
Cотрудничество: @energy_c
РКН: https://clck.ru/3NJCKs”
Завдяки високій частоті оновлень (останні дані отримано 27 жовтня, 2026), канал підтримує актуальність та високий рівень охоплення публікацій. Аналітика показує, що аудиторія активно взаємодіє з контентом, що робить його важливою точкою впливу в категорії Технології та додатки.
fetch('/api/document/1', {
method: 'PATCH',
body: JSON.stringify({ title: 'Draft' })
});
fetch('/api/document/1', {
method: 'PATCH',
body: JSON.stringify({ title: 'Final' })
});
Порядок отправки запросов не гарантирует порядок их применения на сервере. Поэтому итоговое название может оказаться Draft, хотя пользователь последним указал Final.
Один из способов предотвратить перезапись изменений устаревшими данными — оптимистическая блокировка через версионирование данных. Сервер возвращает документ вместе с его версией:
{
"id": 1,
"title": "Draft",
"version": 5
}
При обновлении клиент передаёт версию, на основе которой редактировал документ:
const response = await fetch('/api/document/1', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
title: 'Final',
version: 5
})
});
На бэкенд обновление выполняется только при совпадении версии. Например, в sql:
UPDATE documents
SET title = 'Final',
version = version + 1
WHERE id = 1
AND version = 5;
Если запись уже была изменена другим запросом, условие version = 5 не выполнится и количество обновлённых строк будет равно нулю. Такой же результат возможен, если документ не существует.
В таком случае бэкенд проверяет количество обновлённых строк и может вернуть 409 Conflict при несовпадении версии или 404 Not Found, если документ отсутствует. Фронтенд при конфликте может предложить пользователю обновить данные или разрешить конфликт:
if (response.status === 409) {
throw new Error(
'Документ был изменён. Обновите данные.'
);
}
🔥 Главное преимущество подхода — атомарная проверка версии и обновление записи в базе данных. Это предотвращает незаметную перезапись изменений, но не гарантирует применение последнего отправленного запроса.
📣 Code Ready | #практика• Узнаете, действительно ли переход с JavaScript на WebAssembly ускоряет Flutter-приложения;
• Разберёте результаты 46 тестов производительности: от вычислений и работы с памятью до обработки данных и графики;
• Посмотрите, в каких задачах выигрывает WASM, где быстрее JavaScript и как это влияет на плавность интерфейса.
🔊 Продолжай читать на Habr!📣 Code Ready | #статья
.nav-link:hover {
font-weight: 700;
}
Часто это исправляют фиксированной шириной пунктов меню. Но такой подход плохо работает с переводами, динамическими названиями и адаптивной вёрсткой.
Есть более гибкий приём: заранее зарезервировать место под жирную версию текста.
<a class="nav-link" data-text="Каталог">
Каталог
</a>
.nav-link::before {
content: attr(data-text);
font-weight: 700;
display: block;
height: 0;
overflow: hidden;
visibility: hidden;
}
Псевдоэлемент создаёт невидимую копию надписи с нужной толщиной шрифта. Несмотря на нулевую высоту, его ширина участвует в расчёте размера элемента.
Поэтому ссылка заранее занимает достаточно места для жирного текста. Остаётся добавить само состояние наведения.
.nav-link:is(:hover, :focus-visible) {
font-weight: 700;
}
Теперь изменение толщины шрифта не должно сдвигать соседние элементы, если жирная версия действительно шире обычной.
Важный нюанс: значение data-text нужно поддерживать в соответствии с видимым текстом. Для многострочных подписей и сложной типографики приём стоит проверять отдельно.
🔥 Приём особенно полезен для горизонтальной навигации, вкладок и переключателей, где активный пункт выделяется жирным начертанием.
📣 Code Ready | #совет:invalid подсвечивает ошибки даже в пустой форме, когда пользователь ещё ничего не вводил. Из-за этого приходится добавлять обработчики событий и отслеживать, какие поля уже были затронуты.
Но у CSS есть более точный инструмент — :user-invalid.
Как работает:
• :user-invalid выбирает поле, которое не прошло проверку после взаимодействия пользователя; • : неhas() позволяет родительскому контейнеру реагировать на состояние вложенного поля; • :not(:placeholder-shown) здесь не нужен — браузер сам учитывает момент взаимодействия; • :user-valid позволяет аналогично оформить корректно заполненные поля.В результате можно показывать ошибки в нужный момент, не создавая отдельное JS-состояние для стилизации каждого поля. 📣 Code Ready | #фишка
Оставляю ссылочку: GitHub 📱📣 Code Ready | #репозиторий
<div class="chat">
<div class="messages">
<!-- сообщения -->
</div>
</div>
Зададим ему ограниченную высоту и вертикальную прокрутку:
.chat {
height: 400px;
overflow-y: auto;
}
Если содержимое выше видимой области изменит размер, браузер может скорректировать scrollTop, чтобы сохранить положение опорного элемента.
Для управления этим механизмом существует CSS-свойство overflow-anchor:
.chat {
overflow-anchor: none;
}
Значение none исключает контейнер и его потомков из выбора опорного элемента для scroll anchoring. При этом прокрутка продолжает работать, а размеры содержимого могут изменяться как обычно.
По умолчанию используется auto:
.chat {
overflow-anchor: auto;
}
В таком режиме элементы могут участвовать в выборе опорного узла, если это допускают условия алгоритма.
Чат, в котором новые сообщения добавляются в конец списка:
const chat = document.querySelector('.chat');
const messages = document.querySelector('.messages');
function appendMessage(text) {
const message = document.createElement('div');
message.textContent = text;
messages.append(message);
}
Если требуется самостоятельно управлять прокруткой, можно отключить scroll anchoring:
.chat {
height: 400px;
overflow-y: auto;
overflow-anchor: none;
}
Например, после добавления сообщения можно прокрутить контейнер вниз:
chat.scrollTop = chat.scrollHeight;
Но если пользователь читает историю сообщений, принудительная прокрутка будет мешать.
Поэтому лучше проверять положение до добавления сообщения:
function appendMessage(text) {
const distanceToBottom =
chat.scrollHeight -
chat.scrollTop -
chat.clientHeight;
const shouldScroll = distanceToBottom <= 20;
const message = document.createElement('div');
message.textContent = text;
messages.append(message);
if (shouldScroll) {
chat.scrollTop = chat.scrollHeight;
}
}
Теперь контейнер прокручивается вниз только тогда, когда пользователь уже находился рядом с нижней границей. Здесь overflow-anchor: none отключает автоматическую компенсацию, а js управляет необходимой позицией.
Если у родителя установлено overflow-anchor: none, потомки не могут повторно включить scroll anchoring:
.container {
overflow-anchor: none;
}
.container .item {
overflow-anchor: auto;
}
В данном случае .item всё равно остаётся внутри исключённой области.
Также scroll anchoring не гарантирует компенсацию любых изменений. А поддержка overflow-anchor в Safari ограничена, поэтому для строго определённого поведения лучше использовать js.
🔥 overflow-anchor позволяет управлять участием элементов в scroll anchoring. Свойство полезно для чатов, лент и динамических списков, где положение прокрутки контролируется логикой приложения.
📣 Code Ready | #практикаШпаргалка по CSS-селекторам: группировка через :is() и :where(), выбор связанных элементов с :has(), исключение через :not(), управление состояниями фокуса с :focus-visible и :focus-within(), определение пустых элементов через :empty и позиционная выборка с :nth-child(). Примеры охватывают специфичность, структуру DOM и стилизацию элементов в зависимости от их состояния.
📣 Code Ready | #шпораflex: 1 не гарантирует сжатие элемента до доступной ширины. Содержимое может выходить за границы контейнера из-за автоматического минимального размера flex-элемента.
Рассмотрим контейнер с боковой панелью и основной областью, содержащей длинную строку без пробелов.
<div class="layout">
<aside class="sidebar">Menu</aside>
<main class="content">
<p>VeryLongTextWithoutSpacesVeryLongTextWithoutSpacesVeryLongTextWithoutSpacesVeryLongTextWithoutSpaces</p>
</main>
</div>
При ширине контейнера 400px боковая панель занимает 150px, а основной области остаётся 250px. Но длинная строка может препятствовать её сжатию:
.layout {
display: flex;
width: min(100%, 400px);
}
.sidebar {
flex: 0 0 150px;
}
.content {
flex: 1;
}
Причина — min-width: auto. Для flex-элемента с нескроллируемым вычисленным значением overflow автоматический минимум по главной оси зависит от содержимого. Длинная неразрывная строка может задавать минимальную ширину больше доступной.
flex: 1 не отменяет это ограничение. Чтобы разрешить сжатие, установите нулевой минимум:
.content {
flex: 1;
min-width: 0;
}
Теперь при ширине контейнера 400px .content может занять доступные 250px, но текст всё ещё способен выходить за её границы. Для переноса длинных строк используйте overflow-wrap: anywhere:
.content p {
overflow-wrap: anywhere;
}
overflow-wrap: anywhere также уменьшает min-content, поэтому в этом примере может устранить проблему даже без min-width: 0.
Для однострочного текста с многоточием используйте другой вариант:
.content p {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
Свойства применяются непосредственно к <p>, а min-width: 0 на .content сохраняется.
Альтернатива — overflow: hidden на flex-элементе. Он также обнуляет автоматический минимум по главной оси:
.content {
flex: 1;
overflow: hidden;
}
Но в отличие от min-width: 0, это свойство дополнительно обрезает содержимое и создаёт scroll container без обычной пользовательской прокрутки.
Похожая проблема есть в CSS Grid. Трек 1fr имеет автоматический минимум, из-за которого длинное содержимое может расширять колонку:
.layout {
display: grid;
grid-template-columns: 150px 1fr;
}
Чтобы убрать автоматический минимум трека, используйте minmax(0, 1fr):
.layout {
display: grid;
grid-template-columns: 150px minmax(0, 1fr);
}
Однако это не гарантирует отсутствия переполнения содержимым — перенос или обрезку текста нужно настраивать отдельно.
🔥 flex: 1 и 1fr не гарантируют сжатие содержимого. Во Flexbox используйте min-width: 0, в Grid — minmax(0, 1fr), а перенос и обрезку текста настраивайте отдельно.
📣 Code Ready | #практикаШпаргалка по функциям для работы со строками: нормализация пробельных символов, преобразование регистра, ограничение длины текста, генерация URL-идентификаторов, экранирование HTML-символов, маскирование email-адресов и удаление диакритических знаков.
📣 Code Ready | #шпора<details> позволяет сделать раскрывающийся блок без JS. Но если таких блоков несколько, пользователь может открыть их все одновременно.
Для FAQ это не всегда удобно: длинные ответы растягивают страницу, а открытые секции приходится закрывать вручную. У <details> есть малоизвестный атрибут name.
<details name="faq">
<summary>Первый вопрос</summary>
Первый ответ
</details>
<details name="faq">
<summary>Второй вопрос</summary>
Второй ответ
</details>
Теперь браузер сам следит за состоянием: при открытии второго блока первый автоматически закрывается.
Причём элементы с одинаковым name не обязаны находиться внутри одного контейнера. Они могут располагаться в разных частях DOM и всё равно работать как одна группа.
<details name="faq" open>
<summary>Частый вопрос</summary>
Ответ на него
</details>
В одной группе браузер допускает только один открытый элемент. При этом закрыть все элементы по-прежнему можно. И внешний вид полностью настраивается через CSS.
details[open] {
border-color: royalblue;
}
details::details-content {
padding-block: 12px;
}
Здесь details[open] позволяет стилизовать раскрытый блок, а ::details-content — обращаться непосредственно к содержимому, хотя у этого псевдоэлемента поддержка браузерами отличается от поддержки самого аккордеона.
🔥 Полезно для FAQ, настроек и справочных разделов, где не нужна сложная пользовательская логика.
📣 Code Ready | #советШпаргалка по функциям для работы со строками: нормализация пробельных символов, преобразование регистра, ограничение длины текста, генерация URL-идентификаторов, экранирование HTML-символов, маскирование email-адресов и удаление диакритических знаков.
📣 Code Ready | #шпора:invalid есть неприятная особенность: обязательное пустое поле может считаться невалидным ещё до того, как пользователь начал заполнять форму.
<input type="email" required>
input:invalid {
border-color: #e53935;
}
В результате форма может подсвечивать ошибки сразу после загрузки страницы.
Для этого существует :user-invalid.
input:user-invalid {
border-color: #e53935;
}
Этот псевдокласс учитывает не только результат встроенной проверки HTML, но и факт взаимодействия пользователя с полем. Например, ошибка может появиться после изменения значения и ухода из поля или после попытки отправить форму.
Можно добавить и состояние успешного заполнения.
input:user-valid {
border-color: #2e7d32;
}
В отличие от :valid и :invalid, эти селекторы позволяют не показывать результат проверки слишком рано. Конкретный момент их срабатывания зависит от поведения браузера.
Оба псевдокласса входят в Baseline 2023 и поддерживаются современными браузерами.
🔥 Для форм со встроенной HTML-валидацией это простой способ улучшить обратную связь без дополнительных классов и обработчиков событий.
📣 Code Ready | #советoverflow: hidden или оказываются под соседними элементами. Увеличение z-index не всегда помогает, особенно при наличии вложенных контекстов наложения. Но у браузера есть собственный механизм — верхний слой отображения.
Как работает:
• popover позволяет создавать всплывающие элементы без JS; • popovertarget связывает кнопку с меню и управляет его открытием; • браузер помещает открытое меню в верхний слой, где оно не зависит от обычной иерархии z-index; • :popover-open позволяет стилизовать открытое состояние, а starting-style — анимировать появление.Приём полезен для меню действий, административных панелей, таблиц и интерфейсов со сложной вложенностью. 📣 Code Ready | #фишка
position: fixed исходным containing block служит viewport. Однако некоторые CSS-свойства предков изменяют эту привязку, из-за чего элемент может прокручиваться вместе с контейнером:
.notification {
position: fixed;
top: 20px;
right: 20px;
}
Если .notification находится внутри элемента с transform, отличным от none, этот предок формирует новый containing block. Даже преобразование без визуального смещения меняет систему координат:
<div class="container">
<div class="notification">Notification</div>
</div>
.container {
transform: translateZ(0);
}
.notification {
position: fixed;
top: 20px;
right: 20px;
}
Теперь top и right рассчитываются относительно padding box контейнера, а не viewport. Аналогичное поведение вызывают transform: translate(0, 0), perspective и filter со значениями, отличными от none:
.container {
filter: blur(0);
}
Даже фильтр без видимого эффекта создаёт containing block для фиксированных потомков. Исключение предусмотрено для корневого элемента документа.
Свойство will-change: transform также формирует containing block до применения преобразования. Такой же эффект дают contain: layout, contain: paint, contain: content и contain: strict:
.container {
will-change: transform;
}
При этом stacking context и containing block — разные механизмы. Например, opacity: 0.9 создаёт stacking context, но не изменяет систему координат фиксированных элементов:
.container {
opacity: 0.9;
}
Чтобы исключить влияние преобразованного контейнера, фиксированный элемент можно вынести за пределы его DOM-поддерева. В React для этого применяют createPortal:
import { createPortal } from 'react-dom';
function Notification() {
return createPortal(
<div className="notification">
Notification
</div>,
document.body
);
}
Портал сохраняет компонент в React-дереве, но размещает его DOM-узел вне исходного контейнера. При этом необходимо учитывать стили html и body, а при SSR — доступность document.
🔥 Краткий вывод: position: fixed не гарантирует привязку к viewport. При диагностике проверяйте предков на transform, filter, perspective, will-change, contain, backdrop-filter и content-visibility: auto.
📣 Code Ready | #практикаcodeready
→ Программа HolyJS
→ Купить билет
Реклама. ООО «Джуг Ру Груп». ИНН 7801341446• Вспомните, как раньше создавали бегущие строки, интерактивные элементы и центрировали контент с помощью marquee, applet и center;
• Разберёте, почему до появления Flexbox и Grid разработчикам приходилось использовать float, clear и специальные CSS-хаки;
• Узнаете, как свойство zoom помогало исправлять проблемы Internet Explorer и почему старый CSS иногда выглядит так необычно.
🔊 Продолжай читать на Habr!📣 Code Ready | #статья
