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

Автор: @energy_it

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

Реклама на бирже: https://telega.in/c/code_ready
Download Telegram
Как сделать аккуратный fade по краям контента без псевдоэлементов!

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

Часто для этого добавляют псевдоэлементы с градиентом:
.scroll::after {
position: absolute;
right: 0;
width: 40px;
background: linear-gradient(...);
}


Но это создаёт лишние слои, проблемы с pointer-events и иногда ломает клики.

Есть другой способ — использовать CSS-маску:
.scroll {
mask-image: linear-gradient(to right,
transparent,
black 40px,
black calc(100% - 40px),
transparent
);
}


mask-image управляет прозрачностью элемента, а не рисует поверх него слой.

Чёрный цвет = полностью видимый контент
Прозрачный = плавное исчезновение.

Это хорошо работает для горизонтальных списков:
.scroll {
display: flex;
overflow-x: auto;
mask-image: linear-gradient(to right,
transparent,
black 40px,
black calc(100% - 40px),
transparent
);
}


🔥 В итоге получаем нативный fade-эффект без псевдоэлементов, без лишних слоёв и без JS.

📣 Code Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
17🔥10👍8🤝4
This media is not supported in your browser
VIEW IN TELEGRAM
😍 My-JS — большая база знаний по JavaScript!

Это сайт с подборкой руководств, шпаргалок и полезных материалов для JavaScript-разработчиков. Здесь собраны статьи по TypeScript, React, Node.js, Next.js и другим технологиям. На сайте можно найти объяснения сложных тем, алгоритмы и структуры данных, а также практические гайды по инструментам вроде Docker и GraphQL. Все материалы удобно структурированы.

📌 Оставляю ссылочку: my-js.org

📣 Code Ready | #сайт
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥18👍10🤝91
navigator.sendBeacon для отправки данных при закрытии страницы!

Если нужно отправить аналитику или финальные данные сессии, обычные HTTP-запросы могут не успеть выполниться — пользователь закрыл вкладку или перешёл на другую страницу. Для таких случаев есть navigator.sendBeacon.

Метод ставит данные в очередь на отправку и не блокирует закрытие страницы.

Базовый пример:
navigator.sendBeacon('/analytics', JSON.stringify({
event: 'page_close'
}));


Метод принимает URL и данные. Запрос отправляется методом POST.

Если нужно явно указать Content-Type: application/json, лучше передать Blob:
navigator.sendBeacon(
'/analytics',
new Blob(
[JSON.stringify({ event: 'page_close' })],
{ type: 'application/json' }
)
);


Пример 1 — отправка при скрытии страницы:
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'hidden') {
navigator.sendBeacon('/analytics', JSON.stringify({
event: 'session_end',
time: Date.now()
}));
}
});


visibilitychange часто используют для отправки последних метрик перед уходом пользователя. Обычно это работает стабильнее, чем beforeunload.

Пример 2 — отправка FormData:
const data = new FormData();

data.append('event', 'scroll_depth');
data.append('value', 80);

navigator.sendBeacon('/analytics', data);


Можно отправлять строки, FormData, Blob, URLSearchParams и некоторые бинарные типы данных.

Пример 3 — проверка:
const accepted = navigator.sendBeacon('/analytics', JSON.stringify({
event: 'leave'
}));

console.log('Beacon accepted:', accepted);


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

🔥 Если нужен ответ сервера, кастомные заголовки или полный контроль над запросом, можно использовать fetch с опцией keepalive.

📣 Code Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥15👍12🤝91
🔥12👍10🤝6
Что же выведет консоль?
Anonymous Quiz
41%
A
8%
B
18%
C
32%
D
🔥19👍107🤝3👎2
👩‍💻 Кнопка с эффектом заливки при наведении!

Иногда интерфейс выглядит слишком статичным. Небольшие анимации делают элементы более живыми и помогают пользователю быстрее распознавать интерактивность.

Как работает:
псевдоэлемент ::before создаёт увеличенный слой внутри кнопки;

форма волны формируется через border-radius;

изначально слой расположен ниже кнопки и скрыт;

при :hover волна поднимается вверх, создавая эффект заполнения.


Так можно добавить акцент CTA-кнопкам или карточкам без сложной анимации и без JS.

📣 Code Ready | #фишка
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥14👍10🤝9
📂 Напоминалка по объектам в JavaScript!

Например, объект помогает хранить данные в формате ключ-значение, а через dot notation, bracket notation и destructuring можно быстро получать и использовать нужные свойства.

На картинке — базовые приёмы работы с объектами: создание, доступ к свойствам, изменение значений, добавление новых полей, деструктуризация и методы.

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

📣 Code Ready | #ресурсы
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12🤝109
Почему ellipsis не срабатывает во flex и grid?

Во flex и grid элементы по умолчанию не хотят сжиматься меньше своего контента, из-за этого текст может выталкивать соседей и ломать layout:
.title {
overflow: hidden;
text-overflow: ellipsis;
}


Даже с ellipsis элемент может не обрезаться, потому что ему не разрешено сжиматься:
.item {
min-width: 0;
}


Эта строка явно разрешает элементу ужиматься по доступному пространству, и всё начинает работать как ожидается:
.item {
min-width: 0;
}


Особенно критично для flex и grid-колонок с 1fr, где переполнение встречается чаще всего.

🔥 Если где-то ломается текст или layout — в 50% случаев не хватает именно min-width: 0

📣 Code Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
👍20🔥1310
Проверка условий в массиве без явного цикла!

Когда нужно проверить элементы массива, многие пишут цикл и флаги:
let hasEven = false;

for (const n of numbers) {
if (n % 2 === 0) {
hasEven = true;
break;
}
}


В JS для таких проверок есть нативные методы — some() и every(), которые позволяют обойтись без явного цикла.

Метод some() проверяет, выполняется ли условие хотя бы для одного элемента массива:
const hasEven = numbers.some(n => n % 2 === 0);


Метод every() проверяет, выполняется ли условие для всех элементов массива:
const allEven = numbers.every(n => n % 2 === 0);


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

🔥 Особенно полезно при валидации данных, проверке прав доступа и любой логике, где нужно быстро проверить условие для массива.

📣 Code Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
15👍12🔥11
Как читать элементы массива с конца через at()!

Раньше доступ к элементам с конца массива требовал ручных вычислений длины и это ухудшало читаемость кода.

Например, чтобы получить последний и предпоследний элементы, обычно писали так.

Традиционный способ:
const arr = ["a", "b", "c", "d"];

const last = arr[arr.length - 1];
const prev = arr[arr.length - 2];

console.log(last); // "d"
console.log(prev); // "c"


При сложных выражениях или частых обращениях к последним элементам такой код становится менее читаемым.

Современный метод at() позволяет обращаться к элементам массива с конца через отрицательные индексы:
const arr = ["a", "b", "c", "d"];

arr.at(-1); // "d"
arr.at(-2); // "c"


Метод также поддерживает обычные положительные индексы:
arr.at(0); // "a"
arr.at(2); // "c"


Если индекс выходит за пределы массива, метод возвращает undefined:
arr.at(100);  // undefined
arr.at(-100); // undefined


Один из практических сценариев — работа со стеком, когда нужно быстро посмотреть верхний элемент:
function peek(stack) {
return stack.at(-1);
}


Метод работает не только с массивами, но и со строками:
"hello".at(-1); // "o"


В отличие от charAt(), метод at() поддерживает отрицательные индексы.

Он также доступен для TypedArray:
const bytes = new Uint8Array([10, 20, 30]);

bytes.at(-1); // 30


🔥 Важно: at() не мутирует данные и не создаёт копий — это просто способ получить элемент по индексу. Метод поддерживается современными браузерами и современными версиями Node.js.

📣 Code Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1915🤝10
This media is not supported in your browser
VIEW IN TELEGRAM
☕️ Нашел вам сайт — CSSBattle, в котором ты буквально «сражаешься» в умении писать CSS-код!

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

📌 Оставляю ссылочку: cssbattle.dev

📣 Code Ready | #сайт
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18🔥9🤝94
👩‍💻 Динамичный фон карточки!

Иногда обычной рамки недостаточно — элементу не хватает динамики и акцента. В этом приёме граница становится анимированной и вращается вокруг элемента.

Как работает:
conic-gradient формирует круговой градиент;

псевдоэлемент выносится за пределы карточки через inset;

анимация вращает слой через transform, не затрагивая layout;

вся интерактивность реализована без скриптов.


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

📣 Code Ready | #фишка
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥16👍10🤝101
This media is not supported in your browser
VIEW IN TELEGRAM
👩‍💻 Чтобы не писать одно и то же в React.

ES7+ React/Redux/React-Native snippets — добавляет готовые сниппеты для компонентов, хуков, Redux-логики и других часто используемых конструкций. Достаточно ввести короткое сокращение и получаешь полноценный шаблон с импортами и структурой. Помогает быстрее создавать файлы, избегая рутины.

📣 Code Ready | #vscode
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1811👍11
Почему “едут” размеры некоторых элементов?

По умолчанию (box-sizing: content-box) width и height задают только размер контента, без учёта padding и border. Из-за этого элементы становятся больше, чем ожидаешь, и layout ломается:
.box {
width: 200px;
padding: 20px;
}


Фактическая ширина здесь будет 240px, что часто приводит к переполнениям:
.box {
box-sizing: border-box;
}


Теперь padding и border учитываются внутри заданной ширины, и итоговый размер остаётся 200px:
*,
*::before,
*::after {
box-sizing: border-box;
}


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

🔥 Это снижает количество проблем с размерами и делает layout стабильнее.

📣 Code Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
👍24🔥1311
This media is not supported in your browser
VIEW IN TELEGRAM
👍 JavaScript Interview Questions — база вопросов для подготовки к собеседованиям!

Репозиторий с огромной подборкой вопросов от базовых тем до продвинутых концепций. Собраны сотни вопросов по замыканиям, this, event loop, промисам, прототипам, асинхронности и др., которые регулярно встречаются на собеседованиях. Формат простой и удобный: вопрос, ответ, краткое объяснение.

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


📣 Code Ready | #репозиторий
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21🔥1110
closest(): поиск ближайшего элемента по селектору!

Иногда в обработчике клика вообще не важно, куда именно попали — в текст, иконку или вложенный span. Важно — к какому элементу это всё относится. В таких случаях обычно выручает Element.closest().

Он берёт текущий элемент (event.target) и поднимается вверх по DOM, пока не найдёт первый узел, который подходит под CSS-селектор. Причём проверяет и сам элемент тоже.

Самый простой пример:
const button = event.target.closest('.btn');


Если клик был внутри кнопки — получим её. Если нет — вернётся null.

Чаще всего это используют в делегировании событий. Например, список:
document.addEventListener('click', (e) => {
const item = e.target.closest('.list-item');
if (!item) return;

console.log('clicked:', item.dataset.id);
});


Без closest() здесь обычно начинается проверка e.target, потом parentElement, потом ещё выше — и код быстро превращается в цепочку условий. С closest() это одна строка.

Хорошо видно на вложенных элементах:
document.addEventListener('click', (e) => {
const button = e.target.closest('button[data-action]');
if (!button) return;

handleAction(button.dataset.action);
});


Клик может прийтись в svg, span, что угодно внутри кнопки — логика от этого не ломается.

Иногда добавляют ещё проверку на контейнер:
const container = document.querySelector('.container');

container.addEventListener('click', (e) => {
const item = e.target.closest('.item');
if (!item || !container.contains(item)) return;

console.log('inside container');
});


Это не всегда обязательно, но полезно, если одинаковые селекторы встречаются в разных частях страницы.

Ещё момент, который иногда забывают: если элемент уже подходит под селектор, closest() вернёт его же.
const el = document.querySelector('.card');

console.log(el.closest('.card') === el); // true


🔥 Очевидное, но всё же: селектор должен быть валидным, иначе будет ошибка. В итоге — небольшая штука, но сильно упрощает жизнь, когда работаешь с событиями и вложенной разметкой.

📣 Code Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21🔥129🤝3
📂 Напоминалка по иммутабельным методам!

Например, array.push() изменяет исходный массив, а [...array, item] — создаёт новый без мутации. То же самое с sort(), reverse() и другими — у них есть безопасные аналоги вроде toSorted() и toReversed().

На картинке — 9 мутирующих методов и их иммутабельные альтернативы, которые стоит держать под рукой при работе с массивами.

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

📣 Code Ready | #ресурсы
Please open Telegram to view this post
VIEW IN TELEGRAM
16👍16🔥11
Последовательные async-операции без лишней вложенности!

Когда несколько асинхронных действий зависят друг от друга, часто пишут вложенные .then():
fetch('/data').then(r => {
r.json().then(data => {
fetch(`/more/${data.id}`).then(r2 => {
r2.json().then(console.log);
});
});
});


Такой код быстро превращается в избыточную вложенность обработчиков.

Решение — возвращать следующий Promise из .then():
fetch('/data')
.then(r => r.json())
.then(data => fetch(`/more/${data.id}`))


Каждый .then() получает результат предыдущего и передаёт дальше по цепочке, потому что возвращает Promise:
.then(r => r.json())
.then(console.log)


Ошибки ловятся централизованно в .catch(), если они произошли в цепочке или внутри .then():
.catch(console.error);


Важно: fetch не кидает ошибку на HTTP 4xx/5xx — в реальном коде проверяйте r.ok.

🔥 Такой паттерн делает асинхронный код линейным, убирает лишнюю вложенность и упрощает поддержку.

📣 Code Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1812🔥10
This media is not supported in your browser
VIEW IN TELEGRAM
🐱 HTMLCheatSheet — интерактивная шпаргалка по JavaScript!

Здесь собраны основные конструкции JS с готовыми примерами кода. Переменные, циклы, условия, массивы, строки, события, работа с датами и даже регулярные выражения. Главная фишка — это интерактивность: можно сразу копировать код, скрывать комментарии и использовать сайт как быстрый справочник во время работы.

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

📣 Code Ready | #сайт
Please open Telegram to view this post
VIEW IN TELEGRAM
20👍16🔥11👎1