1) <dialog> 🪟
Признайтесь — вы ставили bootstrap или MUI только ради модалки.
А браузер давно закрыл этот вопрос — и сразу с нормальной доступностью:
<dialog id="alert">
<p>Вы уверены? Это нельзя отменить.</p>
<button onclick="alert.close()">Подумаю ещё</button>
<button onclick="doTheThing()">Да, я понимаю</button>
</dialog>
<button onclick="alert.showModal()">Удалить всё</button>
Никаких зависимостей. Работает. Доступно.
2) Container Queries 📦
Media queries всегда смотрели на окно целиком — и это было источником боли при переиспользовании компонентов. Теперь компонент живёт своей жизнью:
.widget { container-type: inline-size; }
@container (min-width: 500px) {
.widget__body {
display: flex;
gap: 1rem;
}
}Положи его в сайдбар или в центр страницы — он сам разберётся.
3) @supports 🧪
Раньше — полифилы, гадание на кофейной гуще и молитвы перед деплоем.
Теперь просто пишете условие и браузер сам решает:
.hero {
background: #1a1a2e;
}
@supports (background: oklch(50% 0.2 270)) {
.hero {
background: oklch(20% 0.15 270);
}
}Старые браузеры получают fallback, новые — красоту.
4) crypto.getRandomValues 🔐
Вот этот паттерн живёт в миллионе кодовых баз:
const id = Math.random().toString(36).slice(2);
// где-то в продакшене плачет дев
Замените на нормальное решение:
const arr = new Uint8Array(10);
crypto.getRandomValues(arr);
const id = [...arr].map(n => n.toString(16).padStart(2, "0")).join("");
Энтропия реальная, вероятность коллизий — смешная.
5) requestIdleCallback ⏸️
Отправка аналитики прямо в момент рендера — один из способов испортить пользователю жизнь незаметно. Браузер сам скажет, когда у него есть свободное время:
const sendStats = () => {
navigator.sendBeacon("/api/stats", JSON.stringify(stats));
};
"requestIdleCallback" in window
? requestIdleCallback(sendStats)
: setTimeout(sendStats, 300);Safari долго саботировал этот API — fallback обязателен.
6) :focus-within 🎯
Классика жанра: инпут в фокусе, а стилизовать нужно обёртку вокруг него. Раньше это решалось через JS и eventListener. Сейчас:
.field {
border: 2px solid transparent;
transition: border-color 0.2s;
}
.field:focus-within {
border-color: #6c63ff;
}Чисто, без единой строчки скрипта.
7) navigator.onLine 📶
Офлайн — это не баг, это сценарий. Телефон в кармане, лифт, метро — всё это реальность:
const queue = [];
window.addEventListener("offline", () => {
queue.push(getPendingData());
});
window.addEventListener("online", async () => {
while (queue.length) {
await sendToServer(queue.shift());
}
});
Главная ловушка —
online говорит только о наличии сети, но не о том, что ваш сервер жив.8) Speech Recognition API 🎙
Перед тем как добавить ещё один тяжёлый пакет — сначала это:
const Engine = window.SpeechRecognition || window.webkitSpeechRecognition;
if (Engine) {
const voice = new Engine();
voice.lang = "ru-RU";
voice.onresult = ({ results }) => {
handleInput(results[0][0].transcript);
};
voice.start();
}
Работает только в Chromium-браузерах. В продакшен — с осторожностью, для прототипа — идеально.
9) requestAnimationFrame 🎞
setInterval для анимаций — это как делать setTimeout(fn, 16) и надеяться на лучшее. Браузер знает точный момент перерисовки, воспользуйтесь этим:let position = 0;
function loop(timestamp) {
position = Math.sin(timestamp / 800) * 120;
el.style.transform = `translateX(${position}px)`;
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
Плавно, без артефактов, CPU не страдает.
Библиотеки — хорошо. Но перед
npm install стоит спросить себя: а не встроено ли это уже? 😄Что из списка уже в вашем коде?
#web #frontend #javascript #css #webdev