Code Ready | Frontend
21.5K subscribers
1.35K photos
545 videos
17 files
1.06K links
Авторский канал по Frontend разработке.
Ресурсы, гайды, задачи, шпаргалки.
Информация ежедневно пополняется!

Cотрудничество: @energy_c

Реклама на бирже: https://telega.in/channels/code_ready/card

РКН: https://clck.ru/3NJCKs
Download Telegram
📱 HTML Constraint Validation API: валидация форм!

В этом посте собраны основные методы и свойства HTML Constraint Validation API для проверки корректности данных в формах. Рассмотрены программная проверка полей, отображение ошибок, установка пользовательских сообщений, контроль обязательных значений, проверка формата и шаблонов, а также ограничений диапазона и шага.

📣 Code Ready | #шпора
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11👍8❤6🤝1
display: contents — убираем обёртку из CSS-раскладки!

Представим каталог, в котором карточки разбиты на группы. Обёртки нужны для структуры компонентов, но все товары должны находиться в одной сетке.
<div class="product-list">
<div class="product-group">
<article>Товар 1</article>
<article>Товар 2</article>
</div>

<div class="product-group">
<article>Товар 3</article>
</div>
</div>


Если применить Grid к .product-list, элементами сетки станут две группы, а не три карточки.
.product-list {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 16px;
}


Чтобы карточки участвовали в общей сетке, необязательно менять HTML. Достаточно убрать коробку обёртки из CSS-раскладки.
.product-group {
display: contents;
}


Теперь карточки становятся элементами сетки .product-list, хотя их родительские обёртки по-прежнему существуют в DOM.

Тот же приём работает и с Flexbox.
.toolbar {
display: flex;
gap: 12px;
}

.toolbar-group {
display: contents;
}


Важно: элемент с display: contents теряет собственную коробку, поэтому его фон, границы и отступы не отображаются как у обычного блока; для семантически важных обёрток также стоит проверять доступность.

🔥 display: contents позволяет сохранить структуру компонентов и при этом не усложнять CSS-раскладку лишними контейнерами.

📣 Code Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
❤14🔥8👍5
📱 HTML-атрибуты — получение, изменение, удаление и проверка атрибутов элементов!

Шпаргалка по работе с HTML-атрибутами через JavaScript: чтение значений с getAttribute(), добавление и обновление через setAttribute(), удаление с removeAttribute(), проверка наличия через hasAttribute() и переключение с toggleAttribute(). Также рассмотрены получение списка атрибутов через getAttributeNames(), работа с data-атрибутами через dataset и доступ к коллекции attributes.

📣 Code Ready | #шпора
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12👍8❤7
Почему удалённый DOM-элемент может продолжать получать события?

В динамических интерфейсах элементы постоянно создаются и удаляются. Например, модальное окно закрывается, его DOM-узел удаляется, но обработчики событий и ссылки на него могут оставаться в памяти.

Рассмотрим простой пример:
const button = document.querySelector('.action');

button.addEventListener('click', () => {
console.log('Clicked');
});

button.remove();


После remove() кнопка исчезает из документа, но сам объект button продолжает существовать, поскольку на него осталась ссылка.

Более того, обработчик всё ещё можно вызвать:
button.click(); // Clicked


Метод remove() отсоединяет элемент от DOM-дерева, но не уничтожает объект и не удаляет зарегистрированные на нём обработчики.

Это особенно интересно при использовании делегирования событий. Допустим, обработчик зарегистрирован на document:
document.addEventListener('click', (event) => {
console.log(event.target);
});


После удаления кнопки её программный click() уже не дойдёт до document:
button.remove();
button.click();


Причина в изменении пути распространения события. Отсоединённый элемент больше не имеет цепочки предков, ведущей к document.

Но если повторно добавить ту же кнопку в документ, её собственный обработчик продолжит работать:
document.body.append(button);

button.click(); // Clicked


При этом вызов снова достигнет обработчика на document, поскольку элемент вернулся в дерево. Здесь важно различать удаление элемента из документа и освобождение памяти.

Если после удаления на кнопку больше нет достижимых ссылок, сборщик мусора может освободить её вместе с обработчиками, даже если между ними существуют циклические ссылки.

🔥 element.remove() изменяет структуру DOM, а не жизненный цикл js-объекта. Удалённые элементы сохраняют свои обработчики, пока остаются достижимыми. Поэтому при диагностике утечек памяти нужно искать удерживающие ссылки, а не просто подсчитывать количество удалённых DOM-узлов.

📣 Code Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥14👍9❤7
This media is not supported in your browser
VIEW IN TELEGRAM
✍️ React Total — большая подборка материалов для изучения React!

В репозитории собраны полезные ресурсы, которые помогают разобраться в компонентном подходе, работе с состоянием, хуках и построении интерфейсов. Материал пригодится тем, кто хочет систематизировать знания React, лучше понять принципы разработки приложений и найти дополнительные источники для самостоятельного обучения.

Оставляю ссылочку: GitHub 📱


📣 Code Ready | #репозиторий
Please open Telegram to view this post
VIEW IN TELEGRAM
❤16🔥7👍5🤝2👎1
😍 Наглядный гайд на Хабре: «CSS Anchor Positioning в картинках»!

В этой статье:
• Узнаете, как привязывать элементы друг к другу с помощью anchor-name, position-anchor и position-area;
• Разберётесь, как точно управлять расположением элементов через функцию anchor(), даже если они находятся в разных контейнерах;
• Посмотрите, как создавать адаптивные соединительные линии, схемы и цепочки элементов без JavaScript для расчёта координат.

🔊 Продолжай читать на Habr!


📣 Code Ready | #статья
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10👍6🔥4
Как уменьшить скачки текста при загрузке шрифтов без JS?

Когда сайт использует веб-шрифт, браузер может сначала показать текст системным шрифтом, а затем заменить его основным.
Проблема в том, что у шрифтов разные метрики: ширина символов, высота строки и положение базовой линии. Из-за этого заголовки переносятся, кнопки меняют ширину, а блоки сдвигаются.

Обычно подключение выглядит так:
@font-face {
font-family: "Inter";
src: url("/fonts/inter.woff2") format("woff2");
font-display: swap;
}


font-display: swap позволяет быстро показать текст, но не устраняет разницу между основным и запасным шрифтом.

Для этого можно создать отдельное начертание запасного шрифта с откорректированными метриками.
@font-face {
font-family: "Inter Fallback";
src: local("Arial");
size-adjust: 105%;
}


size-adjust масштабирует глифы и метрики запасного шрифта. Значение 105% здесь условное: его нужно рассчитывать под конкретную пару шрифтов.

Теперь указываем оба семейства.
body {
font-family: "Inter", "Inter Fallback", sans-serif;
}


А для более точной подгонки существуют дополнительные дескрипторы.
@font-face {
font-family: "Inter Fallback";
src: local("Arial");
size-adjust: 105%;
ascent-override: 90%;
descent-override: 22%;
line-gap-override: 0%;
}


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

Важно: такой подход уменьшает расхождения при замене шрифта, но не гарантирует полного отсутствия переносов и сдвигов, особенно при разных формах и ширине символов.

🔥 Правильно настроенный запасной шрифт помогает снизить CLS без отказа от font-display: swap и без дополнительных скриптов.

📣 Code Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
❤16👍8🔥4
👩‍💻 CSS, который сам подсвечивает ошибки в HTML!

При разработке легко пропустить изображение без alt, кнопку без type или ссылку-заглушку. Вместо того чтобы искать такие проблемы вручную, можно заставить CSS выделять подозрительные элементы прямо на странице.

Как работает:
• img:not([alt]) находит изображения без атрибута alt;

• button:not([type]) подсвечивает кнопки без явно указанного типа;

• a[href="#"] и a:not([href]) помогают обнаружить ссылки-заглушки и элементы без адреса;

• outline выделяет найденные элементы, не влияя на размеры и расположение блоков.


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

📣 Code Ready | #фишка
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥16👍10❤6
👩‍💻 Управляй целым компонентом через CSS без JS!

Обычно для интерактивных переключателей приходится отслеживать состояние в JavaScript и менять классы элементов. Но CSS позволяет управлять оформлением всей карточки через обычный checkbox.

Как работает:
• appearance: none убирает стандартный вид чекбокса, сохраняя его поведение;

• ::before создаёт бегунок переключателя без лишней разметки;

• :checked позволяет стилизовать активное состояние;

• :has(input:checked) изменяет оформление родительской карточки в зависимости от состояния вложенного поля.


В результате получаем интерактивный компонент с нативным управлением и CSS-анимацией — без обработчиков событий и дополнительных классов. Отлично подходит для переключателей настроек, фильтров и интерактивных карточек.

📣 Code Ready | #фишка
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9🤝6❤5👍1😁1
🔴В 2025 году Россияне заработали 5,3 млрд рублей на арбитраже криптовалют

По данным Минфин 32% граждан покинули своё место работы поскольку в среднем уже в первый месяц смогли заработать 250 000 рублей, а через 2-3 месяца с легкостью вышли на семизначные числа.

Самое смешное, что лишь 8% россиян что-то слышали об этой профессии хотя все инструкции бесплатно лежат на канале Арбитраж Криптовалют

Там объясняют, как имея телефон и доступ в интернет заработать свои первые $3000. Причём разжёвывают так доступно, что поймёт даже ребенок. Кстати, на канале сегодня вышла новая рабочая связка!

Ссылка для входа — https://t.me/+lvVed8tyOGg5ZWNi
Please open Telegram to view this post
VIEW IN TELEGRAM
👎10
Почему getBoundingClientRect() возвращает координаты элемента, которого уже нет на экране?

getBoundingClientRect() не анализирует результат отрисовки элемента. Метод вычисляет ограничивающий прямоугольник его CSS-боксов относительно viewport с учётом прокрутки и трансформаций. Поэтому координаты можно получить даже для элемента, который пользователь не видит:
const rect = element.getBoundingClientRect();

console.log(rect.top, rect.left);


После прокрутки rect.top может стать отрицательным. Это означает, что верхняя граница элемента вышла за пределы viewport, но сам элемент всё ещё может частично пересекать видимую область:
const rect = element.getBoundingClientRect();

console.log(rect.top); // Например, -450


С CSS-трансформациями поведение чуть сложнее: transform изменяет визуальное положение элемента, не меняя его исходную позицию в layout:
.card {
width: 200px;
height: 100px;
transform: translateX(500px);
}


В результате getBoundingClientRect() учитывает трансформацию, а offsetLeft — нет.

При этом методы используют разные системы координат: первый работает относительно viewport, второй — относительно offsetParent. Поэтому значения могут различаться даже без transform:
const card = document.querySelector('.card');

console.log(card.offsetLeft);
console.log(card.getBoundingClientRect().left);


При display: none элемент не формирует CSS-боксов, и метод возвращает нулевые размеры. Но обратное неверно: нулевая ширина или высота не доказывает наличие display: none.

При visibility: hidden и opacity: 0 геометрия сохраняется, несмотря на отсутствие видимого содержимого:
card.style.visibility = 'hidden';

const rect = card.getBoundingClientRect();

console.log(rect.width); // 200
console.log(rect.height); // 100


Для tooltip, dropdown и других позиционируемых компонентов бывает требуется проверить именно пересечение с viewport. Это можно сделать сравнением границ прямоугольника с размерами области просмотра:
function intersectsViewport(element) {
const rect = element.getBoundingClientRect();

return (
rect.width > 0 &&
rect.height > 0 &&
rect.bottom > 0 &&
rect.right > 0 &&
rect.top < window.innerHeight &&
rect.left < window.innerWidth
);
}


Такая проверка учитывает частичное пересечение, но не обнаруживает перекрытие другими элементами, прозрачность, visibility: hidden или обрезку родительскими контейнерами. IntersectionObserver позволяет отслеживать пересечения, но также не гарантирует фактическую видимость.

🔥 getBoundingClientRect() возвращает геометрию, а не результат рендеринга. При позиционировании интерфейсов важно различать наличие координат, пересечение viewport и реальную видимость элемента.

📣 Code Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤7🔥6
This media is not supported in your browser
VIEW IN TELEGRAM
✍️ fe-resources — большая подборка книг и полезных материалов для фронтенд-разработчиков!

В репозитории собраны русскоязычные и англоязычные учебники, статьи, видеокурсы и руководства по JavaScript, React, Redux, CSS, Webpack и устройству браузера. Отдельно есть интерактивные тренажёры для практики, материалы по архитектуре приложений и ресурсы для подготовки к техническим собеседованиям. Удобная коллекция, чтобы находить хорошие источники для изучения фронтенда и углубления знаний.

Оставляю ссылочку: GitHub 📱


📣 Code Ready | #репозиторий
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥5🤝4