Code Ready | Frontend
Авторский канал по Frontend разработке. Ресурсы, гайды, задачи, шпаргалки. Информация ежедневно пополняется! Cотрудничество: @energy_c РКН: https://clck.ru/3NJCKs
Ko'proq ko'rsatish📈 Telegram kanali Code Ready | Frontend analitikasi
Code Ready | Frontend (@code_ready) Rus til segmentidagi kanali faol ishtirokchi. Hozirda hamjamiyat 21 557 obunachidan iborat bo'lib, Texnologiyalar & Aralashmalar toifasida 6 157-o'rinni va Rossiya mintaqasida 30 472-o'rinni egallagan.
📊 Auditoriya ko‘rsatkichlari va dinamika
невідомо sanasidan buyon loyiha tez o‘sib, 21 557 obunachiga ega bo‘ldi.
26 Oktabr, 2026 dagi oxirgi ma’lumotlarga ko‘ra kanal barqaror faollikka ega. Oxirgi 30 kunda obunachilar soni -42 ga, so‘nggi 24 soatda esa -20 ga o‘zgardi va umumiy qamrov yuqori darajada qolmoqda.
- Tasdiqlash holati: Tasdiqlanmagan
- Jalb etish (ER): Auditoriya o‘rtacha 6.43% darajada jalb etiladi. Nashrdan keyingi dastlabki 24 soatda kontent odatda umumiy obunachilar sonining 4.29% ini tashkil etuvchi reaksiyalarni to‘playdi.
- Post qamrovi: Har bir post o‘rtacha 1 386 marta ko‘riladi; birinchi sutkada odatda 925 ta ko‘rish yig‘iladi.
- Reaksiyalar va o‘zaro ta’sir: Auditoriya faol: har bir postga o‘rtacha 23 ta reaksiya keladi.
- Tematik yo‘nalishlar: Kontent css, браузер, интерфейс, загрузка, api kabi asosiy mavzularga jamlangan.
📝 Tavsif va kontent siyosati
Muallif resursni shaxsiy fikrni ifoda etish maydoni sifatida ta’riflaydi:
“Авторский канал по Frontend разработке.
Ресурсы, гайды, задачи, шпаргалки.
Информация ежедневно пополняется!
Cотрудничество: @energy_c
РКН: https://clck.ru/3NJCKs”
Yuqori yangilanish chastotasi (oxirgi ma’lumot 27 Oktabr, 2026 da olingan) sababli kanal doimo dolzarb va katta qamrovli bo‘lib qoladi. Analitika auditoriya kontent bilan faol hamkorlik qilishini, uni Texnologiyalar & Aralashmalar toifasidagi muhim ta’sir nuqtasiga aylantirishini ko‘rsatadi.
:checked в CSS применяется к отмеченным элементам формы — например, checkbox и radio. Он позволяет менять их оформление в зависимости от текущего состояния.
Примеры использования:
• менять цвет выбранного элемента; • создавать кастомные чекбоксы и радиокнопки; • стилизовать связанные элементы через CSS-селекторы; • создавать простые переключатели без JavaScript.По задумке должен работать и с
<option>, но поскольку выпадающий список сильно отличается от системы к системе и от браузера к браузеру, то пока работает только в браузере Chrome на Windows.
📣 Code Ready | #свойствоОставляю ссылочку: GitHub 📱📣 Code Ready | #репозиторий
z-index не является глобальной системой нумерации слоёв страницы. Браузер строит дерево stacking context, где каждый контекст отрисовывается независимо. Значение z-index сравнивается только внутри текущего контекста и не позволяет дочернему элементу напрямую влиять на соседние контексты.
Например, z-index: 999999 у вложенного элемента не гарантирует, что он окажется выше элемента с меньшим значением z-index, если родительский stacking context находится ниже в порядке отрисовки:
.card {
position: relative;
z-index: 1;
}
.modal {
position: absolute;
z-index: 999999;
}
.header {
position: relative;
z-index: 10;
}
Если .modal находится внутри .card, браузер сначала сравнивает .card и .header в родительском stacking context, а уже затем учитывает внутренние слои .card. Высокий z-index дочернего элемента не может изменить положение родительского контекста.
Stacking context создаётся не только через position и z-index. Многие CSS-свойства меняют модель композиции слоёв и создают отдельный контекст наложения:
.component {
opacity: 0.99;
transform: translateZ(0);
filter: blur(5px);
isolation: isolate;
contain: paint;
}
В реальных проектах чаще всего проблемы возникают у модальных окон, dropdown, popover и tooltip-компонентов, когда один из родителей создаёт собственный stacking context:
.layout {
transform: translate3d(0, 0, 0);
}
.dropdown {
position: absolute;
z-index: 999999;
}
В такой ситуации увеличение z-index не помогает, потому что элемент остаётся внутри ограниченного контекста .layout.
Отдельный случай — position: fixed. Обычно такой элемент привязан к viewport, но некоторые свойства родителей изменяют его containing block:
.page {
transform: translateZ(0);
}
.modal {
position: fixed;
inset: 0;
z-index: 10000;
}
Теперь modal рассчитывает позицию относительно .page, а не viewport. Поэтому проблема решается не изменением z-index, а изменением структуры DOM.
Для глобальных интерфейсных слоёв используют отдельный DOM-слот вне основного дерева приложения. Такой подход лежит в основе portal-механизма современных UI-библиотек:
<body>
<div id="app"></div>
<div id="overlay-root"></div>
</body>
Также необходимо учитывать, что не все проблемы перекрытия связаны со stacking context. Например, overflow: hidden может обрезать дочерний элемент независимо от его z-index:
.container {
overflow: hidden;
}
.dropdown {
position: absolute;
z-index: 1000;
}
При отладке проблем со слоями необходимо проверять всю цепочку родителей: наличие stacking context, ограничения overflow, изменённый containing block и фактическое расположение элементов в DOM.
🔥 z-index — это только один параметр системы композиции браузера. В сложных интерфейсах реальный порядок отображения определяется структурой stacking context.
📣 Code Ready | #практика::file-selector-button — псевдоэлемент, представляющий кнопку внутри поля <input type="file">. Позволяет стилизовать её так же, как любую кнопку интерфейса: менять фон, бордеры, скругления, состояния наведения/фокуса и другие стили.
С его помощью можно настроить:
• background — цвет фона; • color — цвет текста; • border — рамку кнопки; • padding — внутренние отступы; • font — оформление текста.Для лучшей доступности обеспечьте заметные стили фокуса (
outline, outline-offset).
📣 Code Ready | #свойство• Разберётесь, почему Flexbox и Grid не гарантируют визуально идеальное выравнивание;
• Узнаете, как метрики шрифтов и высота строки влияют на положение текста;
• Посмотрите, почему иконки рядом с текстом часто «съезжают» и как это исправлять на практике.
🔊 Продолжай читать на Habr!📣 Code Ready | #статья
main thread блокирует выполнение других задач. Даже обычный цикл может превратиться в длительную задачу, если обработка элементов достаточно тяжёлая:
function processItems(items) {
for (const item of items) {
renderItem(item);
}
}
Классический способ разбить такую работу — планировать продолжение через setTimeout(). В современных браузерах для добровольной передачи управления планировщику есть более специализированный механизм — scheduler.yield():
async function processItems(items) {
for (let i = 0; i < items.length; i++) {
renderItem(items[i]);
if ((i + 1) % 100 === 0) {
await scheduler.yield();
}
}
}
scheduler.yield() приостанавливает текущую async-функцию и планирует её продолжение как отдельную задачу, давая браузеру возможность выполнить другую ожидающую работу на main thread:
await scheduler.yield();
// выполнение продолжится позже
Это принципиально отличается от await Promise.resolve(): resolved Promise продолжает выполнение через microtask queue и не обеспечивает полноценную передачу управления event loop для выполнения следующей задачи:
await Promise.resolve();
// продолжение выполняется как microtask
Делать yield() после каждой итерации не стоит: каждая передача управления создаёт дополнительные накладные расходы. Размер порции работы зависит от стоимости конкретных операций, поэтому 100 или 200 итераций — лишь пример, а не универсальное значение.
if ((i + 1) % CHUNK_SIZE === 0) {
await yieldToMain();
}
Поддержка scheduler.yield() пока не универсальна, поэтому стоит предусмотреть запасной вариант:
function yieldToMain() {
if (globalThis.scheduler?.yield) {
return scheduler.yield();
}
return new Promise(resolve => setTimeout(resolve, 0));
}
🔥 scheduler.yield() полезен для кооперативного планирования длительной работы на main thread: обработки больших наборов данных и постепенного обновления сложного UI. Для тяжёлых вычислений, интенсивно использующих процессор, Worker остаётся предпочтительным решением: yield() не переносит вычисления с main thread, а только разбивает их выполнение во времени.
📣 Code Ready | #практикаРазбираем Reflect API и его основные методы для чтения, изменения, проверки и удаления свойств, вызова функций, создания экземпляров, работы с дескрипторами и получения собственных ключей объекта. Reflect применяется для метапрограммирования, низкоуровневой работы с объектами и реализации Proxy-логики с явным результатом операций.
📣 Code Ready | #шпора:autofill — псевдокласс, который находит поля формы, куда браузер сам подставил сохранённые данные: адрес, телефон, почту. Нужен, чтобы подсвеченные браузером поля не выбивались из дизайна формы.
Как работает автозаполнение:
• срабатывает только по инициативе браузера, через JavaScript вызвать его нельзя; • браузер может заполнить сразу несколько полей формы; • поле остаётся :autofill, пока пользователь не изменит значение; • после ручного редактирования оно больше не считается автозаполненным.Не полагайтесь на
:autofill для валидации: это лишь визуальное состояние, а не факт корректности данных.
📣 Code Ready | #свойство<data> позволяет показать пользователю обычный текст и одновременно связать его с другим значением, которое удобно использовать в скриптах или при обработке данных.
В <data> используются:
• содержимое тега — текст, который видит пользователь; • value — машиночитаемое значение; • JavaScript — при необходимости может получить значение через свойство value.Элемент
<data> стоит использовать, когда вы не хотите выделять элементы на вёрстке, например, при помощи <div> или <span>, но вам нужно связать текст с внутренним ID или значением, который вы будете использовать при обработке запросов пользователя.
📣 Code Ready | #атрибутbutton.disabled = true;
input.disabled = true;
link.tabIndex = -1;
disabled применим не ко всем HTML-элементам, а изменение tabindex решает только задачу фокуса. Для блокировки целой области документа существует глобальный атрибут inert:
<main id="content">
<button>Сохранить</button>
<a href="/profile">Профиль</a>
<input type="text">
</main>
Состоянием можно управлять через HTMLElement.inert, без поиска и изменения каждого интерактивного элемента внутри контейнера:
const content = document.querySelector('#content');
content.inert = true;
После установки inert контейнер и его потомки в плоском дереве (flat tree) не могут получать фокус. Это относится и к программному вызову focus():
content.inert = true;
document.querySelector('#content input').focus();
Пользовательская активация также блокируется: клик пользователя по кнопке внутри inert-области не приводит к click на этой кнопке. Программный element.click() при этом следует рассматривать отдельно:
const button = document.querySelector('#content button');
button.addEventListener('click', () => {
console.log('click');
});
content.inert = true;
В отличие от inert, pointer-events: none влияет на определение элемента под указателем, но сам по себе не исключает элементы из последовательной навигации с клавиатуры:
.content {
pointer-events: none;
}
inert действует шире: элементы не получают фокус, пользовательское взаимодействие блокируется, а содержимое исключается из дерева доступности.
Например, основной интерфейс можно деактивировать при открытии выдвижной панели, расположенной вне inert-контейнера:
<main id="content">
<!-- основной интерфейс -->
</main>
<aside id="drawer" hidden>
<!-- выдвижная панель -->
</aside>
Состояние всего фонового интерфейса переключается одной операцией независимо от количества элементов внутри main:
function openDrawer() {
content.inert = true;
drawer.hidden = false;
}
function closeDrawer() {
content.inert = false;
drawer.hidden = true;
}
Для модальных интерфейсов есть <dialog>. Вызов showModal() помещает диалог в верхний слой (top layer), а остальную часть документа браузер делает inert автоматически:
const dialog = document.querySelector('dialog');
dialog.showModal();
Сам inert не задаёт визуальное состояние заблокированной области. При необходимости оно оформляется отдельно через CSS:
[inert] {
opacity: 0.6;
}
🔥 inert позволяет исключить целую область документа из взаимодействия без ручного управления disabled, tabindex и состоянием каждого вложенного элемента.
📣 Code Ready | #практика.card {
padding: calc(6 * 4px);
}
.modal {
gap: calc(4 * 4px);
}
Можно вынести саму логику вычисления в @function.
@function --space(--n) {
result: calc(var(--n) * 4px);
}
И дальше использовать её практически как встроенную CSS-функцию.
.card {
padding: --space(6);
}
.modal {
gap: --space(4);
}
Параметры можно типизировать, чтобы функция принимала только ожидаемые значения.
@function --space(--n <number>) returns <length> {
result: calc(var(--n) * 4px);
}
Причём функция может содержать не только calc(): внутри доступны локальные CSS-переменные и условная логика, а одна пользовательская функция может вызывать другую.
Поддержка пока ограничена.
🔥 Смысл @function не в сокращении пары строк. CSS получает переиспользуемую логику с аргументами и типами — то, ради чего раньше приходилось повторять формулы или переносить вычисления в препроцессор.
📣 Code Ready | #советОставляю ссылочку: GitHub 📱📣 Code Ready | #репозиторий
• Объясняется, как токены превращаются в эмбеддинги и как модель представляет смысл в многомерном пространстве;
• На примере grokking показывается, как нейросеть переходит от запоминания ответов к пониманию общего правила;
• Разбираются внутренние представления LLM и причины неожиданных артефактов в их ответах.
🔊 Продолжайте читать на Habr!➡️ IT Ready | #статья
renderResults(), более старый результат в итоге перезапишет актуальный:
search.addEventListener('input', async event => {
const query = encodeURIComponent(event.target.value);
const response = await fetch(`/api/search?q=${query}`);
renderResults(await response.json());
});
Проблема здесь не в fetch() как таковом, а в отсутствии контроля актуальности асинхронной операции: любой завершившийся запрос получает возможность изменить состояние интерфейса.
Если устаревшие запросы больше не нужны, для fetch() их можно отменять через AbortController:
let controller;
search.addEventListener('input', async event => {
controller?.abort();
controller = new AbortController();
try {
const query = encodeURIComponent(event.target.value);
const response = await fetch(`/api/search?q=${query}`, {
signal: controller.signal
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const results = await response.json();
renderResults(results);
} catch (error) {
if (error.name !== 'AbortError') {
console.error(error);
}
}
});
При следующем вводе abort() переводит предыдущий AbortSignal в состояние aborted. Связанная с ним fetch-операция прерывается, поэтому её устаревший результат не попадёт в renderResults().
AbortSignal нельзя использовать повторно после отмены: он остаётся в состоянии aborted. Для следующей операции необходимо создать новый AbortController:
controller.abort();
controller = new AbortController();
Важно понимать границу такой отмены. abort() прерывает клиентскую fetch-операцию и чтение тела ответа, но не гарантирует прекращение обработки запроса на сервере. К моменту отмены запрос уже мог быть отправлен, а сервер мог начать его обработку.
AbortController и debounce также решают разные задачи. debounce уменьшает количество запускаемых запросов, откладывая выполнение до паузы во вводе. AbortController позволяет прервать клиентскую операцию, которая уже была запущена, но перестала быть актуальной. В интерактивном поиске эти механизмы можно использовать совместно.
При этом отмена — не единственный способ защиты от устаревших результатов. Если операцию нельзя или не требуется отменять, актуальность результата можно проверить непосредственно перед изменением состояния:
let requestId = 0;
search.addEventListener('input', async event => {
const id = ++requestId;
const query = encodeURIComponent(event.target.value);
const response = await fetch(`/api/search?q=${query}`);
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const results = await response.json();
if (id === requestId) {
renderResults(results);
}
});
Здесь каждый запрос получает монотонно возрастающий идентификатор. Изменить интерфейс может только результат последней запущенной операции. Даже если более старый запрос завершится позже, его результат будет проигнорирован.
🔥Основной принцип шире конкретного API: результат асинхронной операции должен изменять состояние только до тех пор, пока эта операция остаётся актуальной.
📣 Code Ready | #практика