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

Автор: @energy_it

РКН: https://clck.ru/3NJCKs

Реклама на бирже: https://telega.in/c/code_ready
Download Telegram
👩‍💻 Эффект проявления изображения!

Через CSS Mask можно создавать интересные эффекты, управляя тем, какие части элемента будут видимы.

Как работает:
mask создаёт альфа-маску поверх изображения;

браузер отображает только разрешённые области;

mask-position двигает маску без изменения размеров элемента;

одновременно можно комбинировать эффект с фильтрами и анимациями.


🔥 Приём отлично подходит для галерей, карточек товаров, портфолио и интерактивных превью изображений.

📣 Code Ready | #фишка
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥20👍7🤝5👎2
This media is not supported in your browser
VIEW IN TELEGRAM
💅 dmitry-osin — шпаргалка по CSS на русском языке!

Очень полезный материал для frontend-разработчиков и всех, кто работает с вёрсткой. Здесь собрана все по CSS — от базовых селекторов и блочной модели до Flexbox, Grid, анимаций, адаптива и современных возможностей CSS. Особенно удобно, что всё структурировано и написано простым языком с примерами.

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


📣 Code Ready | #репозиторий
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥137👍7
Как убрать лишние классы для пустых блоков?

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

Если данных нет — элемент остаётся пустым, но продолжает занимать место.

Обычно это решают через JS или условный рендеринг.
.error {
display: none;
}


А потом отдельно добавляют класс при появлении контента.

Но CSS умеет определять пустые элементы самостоятельно.
.error:empty {
display: none;
}


Теперь блок автоматически скрывается, если внутри ничего нет.

Можно делать и обратную логику.
.card:not(:empty) {
padding: 16px;
}


Отступы появятся только тогда, когда внутри действительно есть контент.

Особенно удобно для:
error,
hint,
description,
badge


Где содержимое может появляться динамически.

🔥 :empty позволяет убрать лишние классы и часть условной логики прямо средствами CSS.

📣 Code Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥20👍12🤝81
📂 Напоминалка для работы с JavaScript DOM!

Например, querySelector() помогает быстро находить элементы на странице, addEventListener() обрабатывать события пользователя, а createElement() динамически создавать новый контент.

На картинке — основные DOM-методы и свойства: поиск элементов, работа с содержимым, атрибутами, классами, событиями и управление структурой документа.

Сохрани, чтобы не потерять!

📣 Code Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥145👍5
Разбираемся зачем нужен event.currentTarget!

При работе с событиями многие используют event.target и не задумываются, что это не всегда тот элемент, на который был повешен обработчик.

Например:
<button class="btn">
<span>Сохранить</span>
</button>


Повесим обработчик на кнопку:
button.addEventListener('click', (event) => {
console.log(event.target);
});


Если кликнуть по тексту внутри span, то в консоль попадёт именно span, а не button.

Потому что event.target всегда указывает на элемент, который стал источником события.

Теперь выведем имя тега:
button.addEventListener('click', (event) => {
console.log(event.target.tagName);
});


Клик по кнопке даст такой результат: BUTTON. А клик по тексту внутри span даст: SPAN.

Из-за этого иногда появляются неожиданные баги:
button.addEventListener('click', (event) => {
event.target.disabled = true;
});


Если событие пришло от вложенного элемента, код будет работать не с кнопкой, а с этим элементом. В результате можно случайно изменить не тот элемент или получить неожиданный результат.

В таких ситуациях обычно нужен event.currentTarget:
button.addEventListener('click', (event) => {
console.log(event.currentTarget);
});


currentTarget всегда содержит элемент, на котором сейчас выполняется обработчик.

То есть:
button.addEventListener('click', (event) => {
console.log(event.target);
console.log(event.currentTarget);
});


При клике по span первым будет исходный элемент события:
event.target — span


А вторым — элемент, на котором выполняется обработчик:
event.currentTarget — button


Особенно хорошо разница видна при делегировании событий:
list.addEventListener('click', (event) => {
console.log(event.target);
console.log(event.currentTarget);
});


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

Ещё один момент: currentTarget существует только во время обработки события.
const saved = event.currentTarget;


После завершения обработки значение event.currentTarget становится null. Поэтому если ссылка нужна позже — её стоит сохранить заранее.

🔥 Простое правило: target отвечает на вопрос «какой элемент стал источником события», а currentTarget — «на каком элементе сейчас выполняется обработчик». Понимание этой разницы помогает избежать множества мелких ошибок при работе с DOM-событиями.

📣 Code Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥14👍98
This media is not supported in your browser
VIEW IN TELEGRAM
💅 Frontend Stuff — коллекция полезных ресурсов для frontend-разработчиков!

На сайте собрана большая база материалов для JavaScript-разработчиков: статьи, библиотеки, фреймворки, инструменты, полезные сервисы и обучающие ресурсы. От базовых инструментов до React, Vue, Node.js и др. Отличный ресурс для веб-разработчиков, которые хотят ускорить работу или найти новые инструменты.

📌 Оставляю ссылочку: frontend-stuff.com

📣 Code Ready | #сайт
Please open Telegram to view this post
VIEW IN TELEGRAM
👍137🤝7
✍️ Нашёл полезную статью на Хабре про современные возможности CSS, которые позволяют избавиться от старых костылей и писать код проще!

В этой статье:
• Показано, как решить проблему прыгающего контента через scrollbar-gutter;
• Разбираются современные CSS-возможности: system-ui, light-dark(), margin-inline и align-content;
• Объясняется, как сделать код чище, короче и удобнее для поддержки без лишних Flexbox и Grid-конструкций.

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


📣 Code Ready | #статья
Please open Telegram to view this post
VIEW IN TELEGRAM
13👍8🔥5
AI-инструменты можно любить и ненавидеть, но работать без них в IT уже практически невозможно 🤩

Коллеги из AvitoTech 11 июля зовут в их офис на Лесной на AI Hardcore Day. Приглашают тех, кто каждый день сталкивается с AI в работе и даже пишет своих AI-агентов. Обещают доклады и нетворкинг-сессию на террасе после — и всё это без записи.

💫 Среди тем:
— Spec-Driven Development: теория, инструменты, практика.
— Разработка и тестирование MCP для внутренних агентных систем аналитики.
— Выпрямляем руки агентов: как сделать MCP удобными и действительно полезными.
— Атаки на GenAI-агентов: OWASP на практике.

Регистрация тут!
Please open Telegram to view this post
VIEW IN TELEGRAM
👎1
Маленькая UI-деталь, которая влияет на восприятие интерфейса!

Часто бывает: кликаешь по button, tab, dropdown-item или card-action и выделяется текст.

Интерфейс сразу выглядит менее качественным.
.button {
user-select: none;
}


Теперь текст внутри элемента нельзя случайно выделить мышью или тапом.

Это особенно полезно для интерактивных элементов.
button,
.tab,
.badge {
user-select: none;
}


Но важно не применять это глобально.
body {
user-select: none;
}


Так можно сломать UX: пользователь не сможет копировать текст.

Используй только там, где выделение реально не нужно.
button,
.control,
.action


Это маленькая деталь, но она заметно улучшает UI.

🔥 user-select: none — простой способ сделать интерфейс визуально чище и приятнее.

📣 Code Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16🤝75
This media is not supported in your browser
VIEW IN TELEGRAM
😍 dreamDevTeamx — большая шпаргалка для фронтенд разработчиков!

Годный репозиторий, в котором собрано много практической информации по разным направлениям разработки. Это база знаний, к которой удобно возвращаться во время обучения, работы или подготовки к собеседованиям. Материал ориентирован именно на практику.

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


📣 Code Ready | #репозиторий
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥43🤝1
Сидеть и работать в корпорации — страшно, жизнь-то мимо проходит. Уходить строить бизнес — страшно, а вдруг прогорит. Один из вариантов — разрабатывать свой пет-проект по вечерам. Многие успешные компании, например, Twitter, создавались именно так. Это не значит, что ваш проект обязательно заработает миллиарды, но заработать больше, чем в найме, и получить ценный опыт — вполне реально.

Перед началом разработки появляется множество вопросов, например:

• Как выбрать идею для пет-проекта?
• Что нужно знать про маркетинг
• Как запуститься и довести до первых продаж не имея бюджета на рекламу?

В телеграм-канале «Твой пет проект», Михаил Табунов делится своим опытом с разработчиками и менеджерами.

Он рассказывает, где искать идею для нового проекта, что нужно знать о маркетинге, как запустить стартап и привлечь первых 10 клиентов, а также о многих других важных вещах.

Подписывайтесь на «Твой пет проект», получайте пользу от практиков рынка!
https://t.me/+8Frwa03ciVlhNTky
👎2
Почему querySelectorAll() не обновляется автоматически?

Иногда кажется, что результат querySelectorAll() как-то привязан к DOM и должен сам обновляться при изменениях на странице. Но это не так — он возвращает фиксированный снимок на момент вызова.
const items = document.querySelectorAll('.item');

console.log(items.length); // 3

document.body.insertAdjacentHTML(
'beforeend',
'<div class="item"></div>'
);

console.log(items.length); // всё ещё 3


После этого items никак не пересчитывается. Это просто сохранённый результат поиска, а не живая коллекция.

Если нужен актуальный список — придётся заново выполнить запрос:
let items = document.querySelectorAll('.item');

document.body.insertAdjacentHTML(
'beforeend',
'<div class="item"></div>'
);

items = document.querySelectorAll('.item');

console.log(items.length); // 4


Из-за этого иногда появляются простые, но неприятные ошибки в динамическом UI. Например, когда элементы добавляются позже, а список уже был сохранён заранее:
const buttons = document.querySelectorAll('.btn');

addNewButton();

// новый элемент сюда уже не попадёт
buttons.forEach(bindHandler);


Человек ожидает, что обработчик навесится на всё, но фактически работает только с тем, что существовало в момент запроса.

Есть и другой вариант поведения — живые коллекции. Например:
const items = document.getElementsByClassName('item');

console.log(items.length); // 3

document.body.insertAdjacentHTML(
'beforeend',
'<div class="item"></div>'
);

console.log(items.length); // 4


Такие коллекции действительно меняются вместе с DOM. К ним относятся getElementsByClassName, getElementsByTagName и element.children. Разница простая: querySelectorAll даёт снимок, а getElementsBy* держат связь с DOM.

При этом NodeList, который возвращает querySelectorAll, можно спокойно перебирать как массив:
const items = document.querySelectorAll('.item');

items.forEach(item => {
console.log(item);
});


Но это всё ещё не массив:
Array.isArray(items); // false


Если нужны методы массива — его нужно явно преобразовать:
const items = [...document.querySelectorAll('.item')];


🔥 На практике querySelectorAll используют чаще именно из-за предсказуемости. Он не меняется сам по себе, и это как раз удобно в реальных приложениях. Для динамики обычно либо делают повторный запрос, либо уходят в делегирование событий.

📣 Code Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥52