Code Ready | Frontend
Авторский канал по Frontend разработке. Ресурсы, гайды, задачи, шпаргалки. Информация ежедневно пополняется! Cотрудничество: @energy_c РКН: https://clck.ru/3NJCKs
Show more📈 Analytical overview of Telegram channel Code Ready | Frontend
Channel Code Ready | Frontend (@code_ready) in the Russian language segment is an active participant. Currently, the community unites 21 557 subscribers, ranking 6 157 in the Technologies & Applications category and 30 472 in the Russia region.
📊 Audience metrics and dynamics
Since its creation on невідомо, the project has demonstrated rapid growth, gathering an audience of 21 557 subscribers.
According to the latest data from 26 October, 2026, the channel demonstrates stable activity. Although there has been a change in the number of participants by -42 over the last 30 days and by -20 over the last 24 hours, overall reach remains high.
- Verification status: Not verified
- Engagement rate (ER): The average audience engagement rate is 6.43%. Within the first 24 hours after publication, content typically collects 4.29% reactions from the total number of subscribers.
- Post reach: On average, each post receives 1 386 views. Within the first day, a publication typically gains 925 views.
- Reactions and interaction: The audience actively supports content: the average number of reactions per post is 23.
- Thematic interests: Content is focused on key topics such as css, браузер, интерфейс, загрузка, api.
📝 Description and content policy
The author describes the resource as a platform for expressing subjective opinions:
“Авторский канал по Frontend разработке.
Ресурсы, гайды, задачи, шпаргалки.
Информация ежедневно пополняется!
Cотрудничество: @energy_c
РКН: https://clck.ru/3NJCKs”
Thanks to the high frequency of updates (latest data received on 27 October, 2026), the channel maintains relevance and a high level of publication reach. Analytics show that the audience actively interacts with content, making it an important point of influence in the Technologies & Applications category.
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 | #статья
