В этом посте собраны основные методы и свойства HTML Constraint Validation API для проверки корректности данных в формах. Рассмотрены программная проверка полей, отображение ошибок, установка пользовательских сообщений, контроль обязательных значений, проверка формата и шаблонов, а также ограничений диапазона и шага.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-раскладки!
Представим каталог, в котором карточки разбиты на группы. Обёртки нужны для структуры компонентов, но все товары должны находиться в одной сетке.
Если применить Grid к
Чтобы карточки участвовали в общей сетке, необязательно менять HTML. Достаточно убрать коробку обёртки из CSS-раскладки.
Теперь карточки становятся элементами сетки
Тот же приём работает и с Flexbox.
Важно: элемент с
🔥
📣 Code Ready | #совет
Представим каталог, в котором карточки разбиты на группы. Обёртки нужны для структуры компонентов, но все товары должны находиться в одной сетке.
<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-раскладку лишними контейнерами.Please open Telegram to view this post
VIEW IN TELEGRAM
❤14🔥8👍5
Шпаргалка по работе с HTML-атрибутами через JavaScript: чтение значений с getAttribute(), добавление и обновление через setAttribute(), удаление с removeAttribute(), проверка наличия через hasAttribute() и переключение с toggleAttribute(). Также рассмотрены получение списка атрибутов через getAttributeNames(), работа с data-атрибутами через dataset и доступ к коллекции attributes.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-узел удаляется, но обработчики событий и ссылки на него могут оставаться в памяти.
Рассмотрим простой пример:
После
Более того, обработчик всё ещё можно вызвать:
Метод
Это особенно интересно при использовании делегирования событий. Допустим, обработчик зарегистрирован на
После удаления кнопки её программный
Причина в изменении пути распространения события. Отсоединённый элемент больше не имеет цепочки предков, ведущей к
Но если повторно добавить ту же кнопку в документ, её собственный обработчик продолжит работать:
При этом вызов снова достигнет обработчика на
Если после удаления на кнопку больше нет достижимых ссылок, сборщик мусора может освободить её вместе с обработчиками, даже если между ними существуют циклические ссылки.
🔥
📣 Code Ready | #практика
В динамических интерфейсах элементы постоянно создаются и удаляются. Например, модальное окно закрывается, его 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-узлов.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, лучше понять принципы разработки приложений и найти дополнительные источники для самостоятельного обучения.
Оставляю ссылочку: GitHub📱
Please open Telegram to view this post
VIEW IN TELEGRAM
❤16🔥7👍5🤝2👎1
В этой статье:
• Узнаете, как привязывать элементы друг к другу с помощью anchor-name, position-anchor и position-area;• Разберётесь, как точно управлять расположением элементов через функцию anchor(), даже если они находятся в разных контейнерах;• Посмотрите, как создавать адаптивные соединительные линии, схемы и цепочки элементов без JavaScript для расчёта координат.🔊 Продолжай читать на Habr!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10👍6🔥4
Как уменьшить скачки текста при загрузке шрифтов без JS?
Когда сайт использует веб-шрифт, браузер может сначала показать текст системным шрифтом, а затем заменить его основным.
Проблема в том, что у шрифтов разные метрики: ширина символов, высота строки и положение базовой линии. Из-за этого заголовки переносятся, кнопки меняют ширину, а блоки сдвигаются.
Обычно подключение выглядит так:
Для этого можно создать отдельное начертание запасного шрифта с откорректированными метриками.
Теперь указываем оба семейства.
А для более точной подгонки существуют дополнительные дескрипторы.
Они позволяют отдельно настроить метрики строки. Значения тоже требуют расчёта, а не подбора на глаз.
Важно: такой подход уменьшает расхождения при замене шрифта, но не гарантирует полного отсутствия переносов и сдвигов, особенно при разных формах и ширине символов.
🔥 Правильно настроенный запасной шрифт помогает снизить CLS без отказа от
📣 Code Ready | #совет
Когда сайт использует веб-шрифт, браузер может сначала показать текст системным шрифтом, а затем заменить его основным.
Проблема в том, что у шрифтов разные метрики: ширина символов, высота строки и положение базовой линии. Из-за этого заголовки переносятся, кнопки меняют ширину, а блоки сдвигаются.
Обычно подключение выглядит так:
@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%;
}Они позволяют отдельно настроить метрики строки. Значения тоже требуют расчёта, а не подбора на глаз.
Важно: такой подход уменьшает расхождения при замене шрифта, но не гарантирует полного отсутствия переносов и сдвигов, особенно при разных формах и ширине символов.
font-display: swap и без дополнительных скриптов.Please open Telegram to view this post
VIEW IN TELEGRAM
❤16👍8🔥4
При разработке легко пропустить изображение без
alt, кнопку без type или ссылку-заглушку. Вместо того чтобы искать такие проблемы вручную, можно заставить CSS выделять подозрительные элементы прямо на странице.Как работает:
• img:not([alt]) находит изображения без атрибута alt;
• button:not([type]) подсвечивает кнопки без явно указанного типа;
• a[href="#"] и a:not([href]) помогают обнаружить ссылки-заглушки и элементы без адреса;
• outline выделяет найденные элементы, не влияя на размеры и расположение блоков.
Достаточно добавить несколько CSS-правил в стили для разработки и потенциальные проблемы разметки сразу станут заметны в интерфейсе. Такой подход не заменяет линтеры, но отлично дополняет их визуальной диагностикой.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥16👍10❤6
Обычно для интерактивных переключателей приходится отслеживать состояние в JavaScript и менять классы элементов. Но CSS позволяет управлять оформлением всей карточки через обычный
checkbox.Как работает:
• appearance: none убирает стандартный вид чекбокса, сохраняя его поведение;
• ::before создаёт бегунок переключателя без лишней разметки;
• :checked позволяет стилизовать активное состояние;
• :has(input:checked) изменяет оформление родительской карточки в зависимости от состояния вложенного поля.
В результате получаем интерактивный компонент с нативным управлением и CSS-анимацией — без обработчиков событий и дополнительных классов. Отлично подходит для переключателей настроек, фильтров и интерактивных карточек.
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
По данным Минфин 32% граждан покинули своё место работы поскольку в среднем уже в первый месяц смогли заработать 250 000 рублей, а через 2-3 месяца с легкостью вышли на семизначные числа.
Самое смешное, что лишь 8% россиян что-то слышали об этой профессии хотя все инструкции бесплатно лежат на канале Арбитраж Криптовалют
Там объясняют, как имея телефон и доступ в интернет заработать свои первые $3000. Причём разжёвывают так доступно, что поймёт даже ребенок. Кстати, на канале сегодня вышла новая рабочая связка!
Ссылка для входа — https://t.me/+lvVed8tyOGg5ZWNi
Please open Telegram to view this post
VIEW IN TELEGRAM
👎10
Почему getBoundingClientRect() возвращает координаты элемента, которого уже нет на экране?
После прокрутки
С CSS-трансформациями поведение чуть сложнее:
В результате
При этом методы используют разные системы координат: первый работает относительно viewport, второй — относительно
При
При
Для tooltip, dropdown и других позиционируемых компонентов бывает требуется проверить именно пересечение с viewport. Это можно сделать сравнением границ прямоугольника с размерами области просмотра:
Такая проверка учитывает частичное пересечение, но не обнаруживает перекрытие другими элементами, прозрачность,
🔥
📣 Code Ready | #практика
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 и реальную видимость элемента.Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤7🔥6
This media is not supported in your browser
VIEW IN TELEGRAM
В репозитории собраны русскоязычные и англоязычные учебники, статьи, видеокурсы и руководства по JavaScript, React, Redux, CSS, Webpack и устройству браузера. Отдельно есть интерактивные тренажёры для практики, материалы по архитектуре приложений и ресурсы для подготовки к техническим собеседованиям. Удобная коллекция, чтобы находить хорошие источники для изучения фронтенда и углубления знаний.
Оставляю ссылочку: GitHub📱
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥5🤝4