КОРИСНІ ОГОЛОШЕННЯ
з етеру Співбесіда рівня Senior Frontend наживо з Олександром Лаврусенко.
Знайомтеся з Мейлтрап — українською імейл-платформою, створеною під потреби розробників.
Високі показники доставки, SMTP i API з набором найпопулярніших бібліотек та найкраща в галузі аналітика.
Скористайтесь промокодом
https://l.rw.rw/serhii_babich_4
***
А також не проґавте нагоди виграти конструктор LEGO Technic Ford GT 2022 від партнерів сьогоднішнього етеру — компанії Brainstack.
Яка версія EcmaScript вийшла після EcmaScript 3?
Відповідь давайте у форму: https://forms.gle/U3hUSJN4ByNGjQTZ9
***
І не забудьте залишити під відео свій коментар! Рівень душності не обмежується ;)
@babichdev
з етеру Співбесіда рівня Senior Frontend наживо з Олександром Лаврусенко.
Знайомтеся з Мейлтрап — українською імейл-платформою, створеною під потреби розробників.
Високі показники доставки, SMTP i API з набором найпопулярніших бібліотек та найкраща в галузі аналітика.
Скористайтесь промокодом
BABICH і отримайте знижку 20% на усі тарифні плани Мейлтрап.https://l.rw.rw/serhii_babich_4
***
А також не проґавте нагоди виграти конструктор LEGO Technic Ford GT 2022 від партнерів сьогоднішнього етеру — компанії Brainstack.
Яка версія EcmaScript вийшла після EcmaScript 3?
Відповідь давайте у форму: https://forms.gle/U3hUSJN4ByNGjQTZ9
***
І не забудьте залишити під відео свій коментар! Рівень душності не обмежується ;)
@babichdev
YouTube
Співбесіда рівня Senior Frontend наживо
Питання від партнера: https://forms.gle/U3hUSJN4ByNGjQTZ9
Час співбесід на каналі "Сергій Бабіч та Дивовижний світ веброзробки"!
Цього четверга до мене на канал завітає Олександр Лаврусенко — розробник, чий шлях почався ще у шкільні часи, провів його через…
Час співбесід на каналі "Сергій Бабіч та Дивовижний світ веброзробки"!
Цього четверга до мене на канал завітає Олександр Лаврусенко — розробник, чий шлях почався ще у шкільні часи, провів його через…
🔥12❤5
#раджу подивитися
Нікіта Галкін, як і обіцяв, записав відео, в якому розбирає на молекули моє нещодавнє вайбвідео про вайбкодинг. Як завжди — системно, методично і надзвичайно інформативно.
Тому, якщо вам припала до душі моя точка зору, я наполегливо рекомендую до перегляду відео Нікіти. В першу чергу тому, що це не протилежна моїй думка, а, швидше, глибокий та вдумливий розбір того ж, про що я говорив у притаманній мені несерйозній манері.
Тож не чекайте, що це буде рознос, хоча й може так здатися ) Це погляд на ту ж тему, але глибший, вдумливіший і послідовніший.
https://youtu.be/rZSydNEcrR4
P.S. Цієї неділі на закритому стримі "Для своїх" дам свою відповідь на цю відповідь, розкажу з чим згодний, а з чим ні. Чекайте на анонс згодом.
@babichdev
Нікіта Галкін, як і обіцяв, записав відео, в якому розбирає на молекули моє нещодавнє вайбвідео про вайбкодинг. Як завжди — системно, методично і надзвичайно інформативно.
Тому, якщо вам припала до душі моя точка зору, я наполегливо рекомендую до перегляду відео Нікіти. В першу чергу тому, що це не протилежна моїй думка, а, швидше, глибокий та вдумливий розбір того ж, про що я говорив у притаманній мені несерйозній манері.
Тож не чекайте, що це буде рознос, хоча й може так здатися ) Це погляд на ту ж тему, але глибший, вдумливіший і послідовніший.
https://youtu.be/rZSydNEcrR4
P.S. Цієї неділі на закритому стримі "Для своїх" дам свою відповідь на цю відповідь, розкажу з чим згодний, а з чим ні. Чекайте на анонс згодом.
@babichdev
YouTube
Vibe Coding
00:00 – Intro
00:58 – Vibe Coding Definition
06:00 – AI Code generation
21:12 – Vibe Coding Tools
00:58 – Vibe Coding Definition
06:00 – AI Code generation
21:12 – Vibe Coding Tools
🔥15❤2👏1
#анонс
Пані та панове, оголошую про стрим "Для своїх" уже цієї неділі!
Будем теревенити про всяке, але насамперед — чи був я неправий у своєму відео про вайбкодинг, чи вдалося Нікіті Галкіну мене присоромити, чи ж вийшло змінити мою думку. От про це й поговоримо.
А ще позбираємо кошти на ЗСУ, а я розіграю серед усіх донатів невеличкий подарунок, тож не проґавте.
І готуйте свої власні питання, звичайно ж!
Реєструйтеся, бо це стрим виключно для своїх!
https://streamyard.com/watch/ETWnhSxUVGrN
Пані та панове, оголошую про стрим "Для своїх" уже цієї неділі!
Будем теревенити про всяке, але насамперед — чи був я неправий у своєму відео про вайбкодинг, чи вдалося Нікіті Галкіну мене присоромити, чи ж вийшло змінити мою думку. От про це й поговоримо.
А ще позбираємо кошти на ЗСУ, а я розіграю серед усіх донатів невеличкий подарунок, тож не проґавте.
І готуйте свої власні питання, звичайно ж!
Реєструйтеся, бо це стрим виключно для своїх!
https://streamyard.com/watch/ETWnhSxUVGrN
StreamYard
Стрим для своїх №2 — Вайбкодинг мене переміг
Зберемось недільного вечора потеревенити про всяке, але насамперед — чи був я правий минулого разу про вайбкодинг, чи вдалося Нікіті Галкіну мене присоромити, а чи змінити мою думку. От про це й поговоримо.
А ще позбираємо кошти на ЗСУ, я ж цього разу ще…
А ще позбираємо кошти на ЗСУ, я ж цього разу ще…
🔥18
#цього_тижня ми з вами:
— Дізналися, що таке Baseline та як він допомагає розробникам обирати сучасні технології;
— Побачили, як можна швидко зробити підказки дл поля вводу за допомогою datalist;
— Поговорили про нативні API HTML-елементів та чому не варто все робити через onClick;
— Святкували першу тисячу підписників, а поділився з вами своїми підписками на класні джерела знань;
— Дивилися етер зі співбесідою рівня Senior Frontend з Олександром Лаврусенко
— А потім дивилися відповідь Нікіти Галкіна на моє відео про вайбкодинг;
Це був насичений тиждень, дякую вам за нього!
P.S. А завтра буде Стрим для своїх. Обовʼязково приходьте, буде цікаво, а ще й корисно, бо збиратимем гроші для ЗСУ. А я розіграю подарунок серед усіх, хто задонатить. До зустрічі!
— Дізналися, що таке Baseline та як він допомагає розробникам обирати сучасні технології;
— Побачили, як можна швидко зробити підказки дл поля вводу за допомогою datalist;
— Поговорили про нативні API HTML-елементів та чому не варто все робити через onClick;
— Святкували першу тисячу підписників, а поділився з вами своїми підписками на класні джерела знань;
— Дивилися етер зі співбесідою рівня Senior Frontend з Олександром Лаврусенко
— А потім дивилися відповідь Нікіти Галкіна на моє відео про вайбкодинг;
Це був насичений тиждень, дякую вам за нього!
P.S. А завтра буде Стрим для своїх. Обовʼязково приходьте, буде цікаво, а ще й корисно, бо збиратимем гроші для ЗСУ. А я розіграю подарунок серед усіх, хто задонатить. До зустрічі!
🔥14❤5
Стрим для своїх доступний у записі, можете переглядати.
Збирали кошти на користь ЗСУ, а я особисто від себе розіграв невеличкий подарунок серед усіх донатів.
Гайда теревенити!
Збирали кошти на користь ЗСУ, а я особисто від себе розіграв невеличкий подарунок серед усіх донатів.
Гайда теревенити!
StreamYard
Стрим для своїх №2 — Вайбкодинг мене переміг
Зберемось недільного вечора потеревенити про всяке, але насамперед — чи був я правий минулого разу про вайбкодинг, чи вдалося Нікіті Галкіну мене присоромити, а чи змінити мою думку. От про це й поговоримо.
А ще позбираємо кошти на ЗСУ, я ж цього разу ще…
А ще позбираємо кошти на ЗСУ, я ж цього разу ще…
❤6🔥3
Бачили вже нову "магічну" фічу у React 19 — View Transition? А знали, що це усього-навсього обгортка над цілком собі бравзерним API? Як ні, то я вам трошечки зараз розповім.
У всіх бравзерах, окрім, очевидно, Firefox, можна користуватися не таким уже й новим View Transition API, яке, по суті, дозволяє створювати красиві анімації переходу між станами сторінки без застосування складних бібліотек.
Під капотом усе настільки просто, що аж трохи нудно. Коли ви ініціюєте View Transition, бравзер просто робить знімок поточного вигляду сторінки, потім — нового стану (після оновлення DOM або переходу на інший документ), і між цими двома “картинками” програє анімацію.
Тобто ви бачите плавний перехід не між реальними DOM-елементами, а між двома скриншотами. А вже після завершення анімації користувачеві показується справжній, оновлений DOM.
Це можна зробити або за допомогою CSS, задаючи анімацію як усій сторінці, так і певним її регіонам:
Або за допомогою JavaScript:
React у цьому плані нічого кардинально нового не вигадує. Він просто пропонує синтаксичний “цукор” у вигляді функції startViewTransition та експериментального компонента unstable_ViewTransition. По суті — той самий document.startViewTransition() під капотом.
Попри те, що View Transitions поки підтримуються лише в Chromium-бравзерах — таких як Chrome, Edge чи Opera — це не причина уникати їх використання. У бравзерах без підтримки (наприклад, Firefox) анімації просто не спрацюють, якщо задавати їх через CSS, ну а для JS треба просто перевіряти підтримку фічі. Тобто функціональність залишається незмінною, а View Transitions виступають як прогресивне покращення. Їх можна сміливо впроваджувати вже зараз, не хвилюючись про деградацію UX.
Тож, підсумовуючи, View Transitions — це не частина React, а повноцінне бравзерне API. React лише пропонує зручний синтаксичний інтерфейс для його використання, не втручаючись у саму логіку анімації. Тому, хоча підтримка поки й обмежена, технічно і концептуально це абсолютно безпечна інновація для поступового впровадження навіть у продакшн.
🔗 MDN
🔗 Smooth transitions with the View Transition API
🔗 React <ViewTransition>
@babichdev
.
У всіх бравзерах, окрім, очевидно, Firefox, можна користуватися не таким уже й новим View Transition API, яке, по суті, дозволяє створювати красиві анімації переходу між станами сторінки без застосування складних бібліотек.
Під капотом усе настільки просто, що аж трохи нудно. Коли ви ініціюєте View Transition, бравзер просто робить знімок поточного вигляду сторінки, потім — нового стану (після оновлення DOM або переходу на інший документ), і між цими двома “картинками” програє анімацію.
Тобто ви бачите плавний перехід не між реальними DOM-елементами, а між двома скриншотами. А вже після завершення анімації користувачеві показується справжній, оновлений DOM.
Це можна зробити або за допомогою CSS, задаючи анімацію як усій сторінці, так і певним її регіонам:
.fade {
view-transition-name: fade;
}
::view-transition-old(fade) {
animation: fade-out 0.3s ease;
}
::view-transition-new(fade) {
animation: fade-in 0.3s ease;
}Або за допомогою JavaScript:
document.startViewTransition(() => {
// оновлення DOM
});React у цьому плані нічого кардинально нового не вигадує. Він просто пропонує синтаксичний “цукор” у вигляді функції startViewTransition та експериментального компонента unstable_ViewTransition. По суті — той самий document.startViewTransition() під капотом.
import { unstable_ViewTransition as ViewTransition } from 'react';
<ViewTransition>
<div>...</div>
</ViewTransition>Попри те, що View Transitions поки підтримуються лише в Chromium-бравзерах — таких як Chrome, Edge чи Opera — це не причина уникати їх використання. У бравзерах без підтримки (наприклад, Firefox) анімації просто не спрацюють, якщо задавати їх через CSS, ну а для JS треба просто перевіряти підтримку фічі. Тобто функціональність залишається незмінною, а View Transitions виступають як прогресивне покращення. Їх можна сміливо впроваджувати вже зараз, не хвилюючись про деградацію UX.
За вподобайки й поширення окремо нагадати, чи самі все знаєте?
Тож, підсумовуючи, View Transitions — це не частина React, а повноцінне бравзерне API. React лише пропонує зручний синтаксичний інтерфейс для його використання, не втручаючись у саму логіку анімації. Тому, хоча підтримка поки й обмежена, технічно і концептуально це абсолютно безпечна інновація для поступового впровадження навіть у продакшн.
@babichdev
.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥88❤12👏2
А чи не час нам нарешті познайомитись?
Нас тут уже понад тисячу — і мені дуже цікаво, хто ви, мої любі читачі.
Почнімо з простого: чим ви займаєтесь у розробці?
Нас тут уже понад тисячу — і мені дуже цікаво, хто ви, мої любі читачі.
Почнімо з простого: чим ви займаєтесь у розробці?
Final Results
51%
⚛️ Frontend (HTML/CSS/JS, React, Vue тощо)
29%
🧱 Fullstack (і фронт, і бек — на всі руки майстер)
6%
⚙️ Backend (але чомусь люблю читати про frontend)
11%
🐣 Починаю — вчуся, пробую, досліджую
4%
🤷 Інше (DevOps, тестування, UX або просто цікаво)
Ну, а ввечері перед сном ще запитаю про досвід.
У кожного свій шлях, але цікаво — на якому етапі ви зараз?
У кожного свій шлях, але цікаво — на якому етапі ви зараз?
Final Results
19%
🐣 Трейні / Курси
20%
🪴 Junior
33%
🔧 Middle
16%
🧭 Senior
8%
🦉 Tech / Team Lead
4%
👀 Я просто подивиться
Дивитись можна, чіпати не можна?
Часто виникає потреба “вимкнути” якийсь елемент, щоб він узагалі жодним чином не реагував на дії користувача: ні на кліки, ні на фокус. Зазвичай це або pointer-events: none, або event.preventDefault(), чи якісь інші трюки. А то й усе вкупі з tabindex="-1".
Однак в HTML уже давно існує спосіб надійно позбавити елемент будь-якої інтерактивности, а ба більше — викинути його з accessibility tree, “заховавши” від очей скринрідерів.
Це атрибут
Що в JS робиться ось так:
Якщо зробити елемент інертним, то весь його вміст стане повністю й остаточно неактивним для користувача, а також повністю зникне з радарів скринрідерів. І так, “розінертити” дочірні елементи не вийде — атрибут inert не має значення false, і інертність завжди наслідується.
inert входить до Baseline з 2023 року й підтримується всіма основними браузерами. Проте, у Safari (очікувано) є один нюанс: текст усередині inert-елемента все ще можна знайти при пошуку по сторінці (Cmd+F).
Чи можна його використовувати вже? Абсолютно так. За винятком цього невеликого бага, inert працює однаково й передбачувано в усіх браузерах, дозволяючи одним-єдиним атрибутом уникнути потреби городити купу костилів лише для того, щоб користувач не міг клікнути або табнутись у якийсь елемент.
Цим фактом особливо спішу з вами поділитись, бо сам дізнався про inert, обираючи тему для наступного допису.
А для вас це теж новина?
MDN
@babichdev
Часто виникає потреба “вимкнути” якийсь елемент, щоб він узагалі жодним чином не реагував на дії користувача: ні на кліки, ні на фокус. Зазвичай це або pointer-events: none, або event.preventDefault(), чи якісь інші трюки. А то й усе вкупі з tabindex="-1".
Однак в HTML уже давно існує спосіб надійно позбавити елемент будь-якої інтерактивности, а ба більше — викинути його з accessibility tree, “заховавши” від очей скринрідерів.
Це атрибут
inert, який відображає однойменну властивість DOM-елемента:<main id="my-content" inert>
<p>Щось неважливе</p>
</main>
Що в JS робиться ось так:
document.getElementById('my-content').inert = true;Якщо зробити елемент інертним, то весь його вміст стане повністю й остаточно неактивним для користувача, а також повністю зникне з радарів скринрідерів. І так, “розінертити” дочірні елементи не вийде — атрибут inert не має значення false, і інертність завжди наслідується.
І ви не будьте інертними — ставте вподобайки та поширюйте допис.
inert входить до Baseline з 2023 року й підтримується всіма основними браузерами. Проте, у Safari (очікувано) є один нюанс: текст усередині inert-елемента все ще можна знайти при пошуку по сторінці (Cmd+F).
Чи можна його використовувати вже? Абсолютно так. За винятком цього невеликого бага, inert працює однаково й передбачувано в усіх браузерах, дозволяючи одним-єдиним атрибутом уникнути потреби городити купу костилів лише для того, щоб користувач не міг клікнути або табнутись у якийсь елемент.
Цим фактом особливо спішу з вами поділитись, бо сам дізнався про inert, обираючи тему для наступного допису.
А для вас це теж новина?
MDN
@babichdev
🔥116❤20
Ну і останнє опитування з серії "Хто тут?!"
З чим ви працюєте, вчитеся працювати, чи просто цікавитеся?
(можна обрати кілька варіантів)
З чим ви працюєте, вчитеся працювати, чи просто цікавитеся?
(можна обрати кілька варіантів)
Final Results
42%
💻 Чистий, як сльоза, веб — HTML/CSS/JS
68%
⚛️ Невтопимий React / Next.js
14%
🌿 Вічнозелений Vue / Nuxt
15%
🔺 Суворий Angular / Nest
3%
⚡️ Витончені Svelte / Solid / Astro
22%
🧱 Тільки бекенд, тільки хардкор (NodeJS, Python)
4%
🤹 Екзотична екзотика (Rust, Go, WASM, може COBOL)
3%
👀 Не програмую, але цікавлюсь
На DOU Day за 500₴
Дарую квиток за донат на ЗСУ!
Друзі, цьогоріч я вперше виступаю на DOU Day 2025 — і дуже хочу, щоб хтось із вас був там теж. Це чудова нагода відвідати крутезний захід, і зустрітися особисто. Усе, що треба — просто долучитися до збору на РЕБ для в/ч А3892.
Кожні 500 грн — ще один шанс виграти.
Ціль — 260 000 грн.
🔗 Банка:
https://send.monobank.ua/jar/4Pc6zfoth2
💳 Картка:
4441111124945795
Переможця оберу серед усіх донатерів у банці — в п'ятницю, 9 травня.
в коментарях є фото листа-прохання від військової частини
@babichdev
Дарую квиток за донат на ЗСУ!
Друзі, цьогоріч я вперше виступаю на DOU Day 2025 — і дуже хочу, щоб хтось із вас був там теж. Це чудова нагода відвідати крутезний захід, і зустрітися особисто. Усе, що треба — просто долучитися до збору на РЕБ для в/ч А3892.
Кожні 500 грн — ще один шанс виграти.
Ціль — 260 000 грн.
🔗 Банка:
https://send.monobank.ua/jar/4Pc6zfoth2
💳 Картка:
4441111124945795
Переможця оберу серед усіх донатерів у банці — в п'ятницю, 9 травня.
в коментарях є фото листа-прохання від військової частини
@babichdev
🔥21
Нещодавно я розповідав про такий метод HTML-елемента, як closest, який шукає найближчий батьківський елемент, що відповідає заданому селектору. А сьогодні хочу поділитися з вами іншим методом, що нічого не шукає, але відповідає на питання — "А ось цей елемент точно справжній сантехнік той, що треба?"
І це —
Якщо повного співпадіння не буде, то й поверне він false:
На відміну від closest, matches перевіряє суто цільовий елемент і не шукає інших збігів. Звичайно, якщо обом методам дати однаковий і точний селектор — обидва спрацюють позитивно. Але якщо селектор “не точний”, closest цілком може повернути когось із батьків, а от matches скаже чітке “ні”.
Що цікаво, обидва методи працюють зі складними селекторами, включно з псевдокласами, тобто чудово справляться з отаким:
Але у випадку з тим же :not можуть бути нюанси. Коли я бавився з цим прикладом, то селектор вище чудово спрацьовував, а от ось такий:
уже чомусь ні, хоча в CSS цей селектор працює без проблем
Тож, якщо вам потрібно просто дізнатися, чи елемент відповідає селектору, і нічого більше, то ваш вибір — matches. Уявіть, що вам потрібно видалити елемент, тільки якщо він знаходиться в третьому за порядком section, але лише в тому випадку, якщо цей section має інші подібні елементи, а потрібний елемент — не останній.
Звичними нам методами це вимагало б купу переборів DOM і перевірок, а так — один кучерявий селектор і справу зроблено!
Підтримується абсолютно всіма актуальними бравзерами і є частиною Baseline.
🔗 MDN
⚡️ @babichdev
***
P.S. До речі, ви вже взяли участь в розіграші квитка на DOU Day усього за 500 гривень? Якщо ні — не зволікайте!
І це —
Element.matches, який просто перевіряє елемент, на якому він викликаний, на предмет відповідності селектору:<div class="container">
<div class="my-element"></div>
</div>
<noscript>
el.matches('.container .my-element'); // true
</noscript>
Якщо повного співпадіння не буде, то й поверне він false:
el.matches('.container'); // falseНа відміну від closest, matches перевіряє суто цільовий елемент і не шукає інших збігів. Звичайно, якщо обом методам дати однаковий і точний селектор — обидва спрацюють позитивно. Але якщо селектор “не точний”, closest цілком може повернути когось із батьків, а от matches скаже чітке “ні”.
Поки ми тут, не забудьте поставити вподобайку та поширити допис ;)
Що цікаво, обидва методи працюють зі складними селекторами, включно з псевдокласами, тобто чудово справляться з отаким:
:not(.container:first-child):hover .my-element
Але у випадку з тим же :not можуть бути нюанси. Коли я бавився з цим прикладом, то селектор вище чудово спрацьовував, а от ось такий:
.container:not(:first-child):hover .my-element
уже чомусь ні, хоча в CSS цей селектор працює без проблем
Тож, якщо вам потрібно просто дізнатися, чи елемент відповідає селектору, і нічого більше, то ваш вибір — matches. Уявіть, що вам потрібно видалити елемент, тільки якщо він знаходиться в третьому за порядком section, але лише в тому випадку, якщо цей section має інші подібні елементи, а потрібний елемент — не останній.
Звичними нам методами це вимагало б купу переборів DOM і перевірок, а так — один кучерявий селектор і справу зроблено!
Підтримується абсолютно всіма актуальними бравзерами і є частиною Baseline.
***
P.S. До речі, ви вже взяли участь в розіграші квитка на DOU Day усього за 500 гривень? Якщо ні — не зволікайте!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥44❤7👏4
Знаєте, коли я востаннє відчув невимовну радість від коду?
Вчора. І це було ніби вперше.
З роками, з досвідом, коли вже зробив, бачив, пробував стільки всього, починає здаватися, що тебе вже нічого не здивує. Ти тримав у руках jQuery 1.4 і верстав під IE6. Ти бачив стрімкий зліт і ганебну смерть AngularJS. Спостерігав на власні очі за народженням React — і досі чекаєш, коли згасне гайп навколо нього.
Але навіть після всього цього… досі по-дитячому щиру радість викликає одне просте:
ВОНО РОБЕ.
Коли ти припускаєш методом пальця до носа, що щось мало б спрацювати — і таки спрацьовує. Коли кілька днів копаєш баг, і в підсумку рішення — в один рядочок. А часом і в один символ. Коли складна задача раптом складається в елегантне рішення, яке ти колись давно бачив у статті — і забув.
І от ти записуєш цю думку кодом — і воно робе! Саме так, як уявляв: швидко, точно, надійно. І відчуваєш не просто задоволення. Відчуваєш — це зробив я!
Ці моменти — найцінніше для мене в щоденній роботі.
Так, наша робота давно вже ширша, ніж просто написання коду. І, будьмо чесні, кодинг — далеко не головна частина.
Але саме з цих маленьких митей відкриття й складається моє захоплення фахом.
***
P.S. Лишився лише один день до завершення розіграшу квитка на DOU Day 2025. Ви вже долучились?
P.P.S. А від чого ж я відчув таку невимовну радість учора? Якщо цей допис збере понад сотню реакцій і 500 переглядів — поділюся з вами завтра.
@babichdev
Вчора. І це було ніби вперше.
З роками, з досвідом, коли вже зробив, бачив, пробував стільки всього, починає здаватися, що тебе вже нічого не здивує. Ти тримав у руках jQuery 1.4 і верстав під IE6. Ти бачив стрімкий зліт і ганебну смерть AngularJS. Спостерігав на власні очі за народженням React — і досі чекаєш, коли згасне гайп навколо нього.
Але навіть після всього цього… досі по-дитячому щиру радість викликає одне просте:
ВОНО РОБЕ.
Коли ти припускаєш методом пальця до носа, що щось мало б спрацювати — і таки спрацьовує. Коли кілька днів копаєш баг, і в підсумку рішення — в один рядочок. А часом і в один символ. Коли складна задача раптом складається в елегантне рішення, яке ти колись давно бачив у статті — і забув.
І от ти записуєш цю думку кодом — і воно робе! Саме так, як уявляв: швидко, точно, надійно. І відчуваєш не просто задоволення. Відчуваєш — це зробив я!
Ці моменти — найцінніше для мене в щоденній роботі.
Так, наша робота давно вже ширша, ніж просто написання коду. І, будьмо чесні, кодинг — далеко не головна частина.
Але саме з цих маленьких митей відкриття й складається моє захоплення фахом.
***
P.S. Лишився лише один день до завершення розіграшу квитка на DOU Day 2025. Ви вже долучились?
P.P.S. А від чого ж я відчув таку невимовну радість учора? Якщо цей допис збере понад сотню реакцій і 500 переглядів — поділюся з вами завтра.
@babichdev
❤108🔥27
Що ж це за задача, рішення якої принесло мені днями стільки задоволення, що я аж цілий допис написав про це відчуття?
Ось вона — на ілюстрації до допису. Треба було зробити картку з динамічним лейаутом, де ширина першого елемента дорівнює найширшому з усіх, а висота самої картки — динамічна. Картки мають тягатися драг-н-дропом, при цьому використовуються наші внутрішні компоненти з дизайн-системи, які додають кілька обгорток, а сам вміст вставляється вже вглиб.
Очевидно, що таблиця не підійде (але я б її не взяв і так). Тому вибір очевидний — CSS Grid.
Отут постає кілька вимог, які дещо можуть завадити швидкій та наївній імплементації:
— ширина першої колонки — спільна, бо там номер картки;
— висота — довільна, однак grid за замовчуванням має однакові рядки;
І тут я згадав про subgrid:
Тут нюанс — якщо між головною сіткою і "наслідувачем" є обгортки, їм усім треба так само “прокинути” цю сітку:
І тоді сітка буде спільна для усіх елементів, незалежно, як вони між собою вкладені. Але лишається ще одне — динамічна висота картки. Тут мені трошки довелося подумати, але рішення виявилося настільки ж елегантним, як і простим:
Voila! — картки в сітці кожна має свою власну висоту!
І от коли все стало на свої місця, клацнуло як останні детальки LEGO, от тоді я й відчув ту мимолітну ейфорію, про яку писав.
Адже задоволення можна отримати не лише, якщо займатися тривалим, кхм, кодингом, а й тоді, коли вдається вирішити задачу в простий, проте елегантний спосіб, замість городити складне заради самої складности, рішення.
🔔 Тим часом розіграш квитка на DOU Day усього за 500 грн відбудеться уже сьогодні ввечері! Тож не зволікайте, аби не впустити таку нагоду!
@babichdev
.
Ось вона — на ілюстрації до допису. Треба було зробити картку з динамічним лейаутом, де ширина першого елемента дорівнює найширшому з усіх, а висота самої картки — динамічна. Картки мають тягатися драг-н-дропом, при цьому використовуються наші внутрішні компоненти з дизайн-системи, які додають кілька обгорток, а сам вміст вставляється вже вглиб.
Очевидно, що таблиця не підійде (але я б її не взяв і так). Тому вибір очевидний — CSS Grid.
Отут постає кілька вимог, які дещо можуть завадити швидкій та наївній імплементації:
— ширина першої колонки — спільна, бо там номер картки;
— висота — довільна, однак grid за замовчуванням має однакові рядки;
І тут я згадав про subgrid:
.container {
display: grid;
grid-template-columns: min-content 1fr;
}
.card {
display: grid;
grid-template-columns: subgrid;
}Тут нюанс — якщо між головною сіткою і "наслідувачем" є обгортки, їм усім треба так само “прокинути” цю сітку:
:where(.wrapper-1, .wrapper-2, …, .wrapper-n, .card) {
display: grid;
grid-template-columns: subgrid;
}І тоді сітка буде спільна для усіх елементів, незалежно, як вони між собою вкладені. Але лишається ще одне — динамічна висота картки. Тут мені трошки довелося подумати, але рішення виявилося настільки ж елегантним, як і простим:
.card {
height: max-content;
}Voila! — картки в сітці кожна має свою власну висоту!
І от коли все стало на свої місця, клацнуло як останні детальки LEGO, от тоді я й відчув ту мимолітну ейфорію, про яку писав.
Адже задоволення можна отримати не лише, якщо займатися тривалим, кхм, кодингом, а й тоді, коли вдається вирішити задачу в простий, проте елегантний спосіб, замість городити складне заради самої складности, рішення.
@babichdev
.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥49❤8👏8
#цього_тижня
— Зазирнули по той бік ViewTransition у React і зʼясували, що це всього-на-всього обгортка над браузерним View Transition API.
— Познайомилися з атрибутом inert, який дозволяє зробити елемент видимим для ока, але невидимим для всього іншого.
— Розібрали, чим корисний метод Element.matches() і чим він відрізняється від Element.closest().
— Я поділився, які маленькі речі приносять мені справжнє задоволення в коді.
— А наступного дня показав, який саме код надихнув мене на попередній допис.
✨ А ще — разом з вами ми зібрали 25 642 грн на користь ЗСУ!
Який із дописів цього тижня сподобався вам найбільше? Напишіть у коментарях 👇
👍 @babichdev
.
— Зазирнули по той бік ViewTransition у React і зʼясували, що це всього-на-всього обгортка над браузерним View Transition API.
— Познайомилися з атрибутом inert, який дозволяє зробити елемент видимим для ока, але невидимим для всього іншого.
— Розібрали, чим корисний метод Element.matches() і чим він відрізняється від Element.closest().
— Я поділився, які маленькі речі приносять мені справжнє задоволення в коді.
— А наступного дня показав, який саме код надихнув мене на попередній допис.
✨ А ще — разом з вами ми зібрали 25 642 грн на користь ЗСУ!
Який із дописів цього тижня сподобався вам найбільше? Напишіть у коментарях 👇
.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥26❤6👏4
Що приховують три крапки?
Вітаю, друзі! Сьогодні розповім вам про деякі неочевидні підводні камені так званого spread-оператора. Я сподіваюсь, ви вже в курсі, для чого він існує, тож перейду відразу до прихованих нюансів.
Порядок важливий
Коли ви "підмішуєте" обʼєкт, то значення будуть застосуватись в порядку додавання в новий обʼєкт:
Останнє входження ключа перезаписує попереднє. Spread — це не злиття, а послідовне копіювання полів з обʼєктів у новий.
undefined в масивах і обʼєктах
Ви спокійно можете розгорнути той же undefined або null в обʼєкт, а от з масивом такий трюк не пройде.
Усе через те, що масив вимагає, аби вхідний обʼєкт був Iterable, тобто такий, яким можна пройтися з Symbol.iterator, і nullish значення, очевидно такими не є. А от звичайний обʼєкт не такий вибагливий, і йому достатньо будь-якого значення, до якого можна застосувати Object.keys. У випадку з null та undefined цей метод просто поверне порожній список.
Object ⇄ Array? Ні.
Рівно з тієї самої причини ми можемо розмазати масив в обʼєкт, але не можемо зробити навпаки:
Spread у масиві очікує ітерабельність — тобто наявність Symbol.iterator. Обʼєкти цього не мають (за замовчуванням), тому розгортання летить з помилкою.
Натомість spread в обʼєкті потребує лише перелічуваних властивостей. А масив — це просто обʼєкт із числовими ключами, які чудово підходять під це визначення.
... не любить порожнечі
Spread-оператор не просто “копіює” масив — він перетворює його дірки на явно присутні undefined.
У масиві a на індексах 1, 2, 3 немає значень — це так звані дірки (sparse elements). Але при
... не копіює вміст обʼєкта
Технічно. Він поверхнево копіює перший рівень масива або обʼєкта. І якщо там примітивні значення, то можна сказати, це "копія". Але якщо є вкладеності, то
А ще
***
Якщо дізналися щось нове — напишіть у коментарях, що саме здивувало чи стало у пригоді.
А далі — обирати вам! Про що буде наступний допис?
🔥 — Дірки в масивах: як вони зʼявляються і що ламають
❤️ — Symbol.iterator: ітерабельність під капотом
🤔 — Чи настільки різні масиви та обʼєкти?
✅ @babichdev
.
Вітаю, друзі! Сьогодні розповім вам про деякі неочевидні підводні камені так званого spread-оператора. Я сподіваюсь, ви вже в курсі, для чого він існує, тож перейду відразу до прихованих нюансів.
Порядок важливий
Коли ви "підмішуєте" обʼєкт, то значення будуть застосуватись в порядку додавання в новий обʼєкт:
{ a: 1, b: 2, ...{ b: 3 } } // { a: 1, b: 3 }
{ ...{ b: 3 }, a: 1, b: 2 } // { a: 1, b: 2 }Останнє входження ключа перезаписує попереднє. Spread — це не злиття, а послідовне копіювання полів з обʼєктів у новий.
undefined в масивах і обʼєктах
Ви спокійно можете розгорнути той же undefined або null в обʼєкт, а от з масивом такий трюк не пройде.
{ ...undefined } // {}
[...undefined] // 💥 TypeErrorУсе через те, що масив вимагає, аби вхідний обʼєкт був Iterable, тобто такий, яким можна пройтися з Symbol.iterator, і nullish значення, очевидно такими не є. А от звичайний обʼєкт не такий вибагливий, і йому достатньо будь-якого значення, до якого можна застосувати Object.keys. У випадку з null та undefined цей метод просто поверне порожній список.
Object ⇄ Array? Ні.
Рівно з тієї самої причини ми можемо розмазати масив в обʼєкт, але не можемо зробити навпаки:
[...{ a: 1 }] // 💥 TypeError: object is not iterable
{ ...[1, 2] } // { 0: 1, 1: 2 }Spread у масиві очікує ітерабельність — тобто наявність Symbol.iterator. Обʼєкти цього не мають (за замовчуванням), тому розгортання летить з помилкою.
Натомість spread в обʼєкті потребує лише перелічуваних властивостей. А масив — це просто обʼєкт із числовими ключами, які чудово підходять під це визначення.
... не любить порожнечі
const a = [1, , , , 5]; // [1, empty × 3, 5]
const b = [...a]; // [1, undefined, undefined, undefined, 5]
console.log(1 in a); // false
console.log(1 in b); // true
Spread-оператор не просто “копіює” масив — він перетворює його дірки на явно присутні undefined.
У масиві a на індексах 1, 2, 3 немає значень — це так звані дірки (sparse elements). Але при
...a вони ущільнюються: JavaScript вставляє на їхнє місце undefined, і ці індекси стають реально присутніми в структурі масиву.... не копіює вміст обʼєкта
Технічно. Він поверхнево копіює перший рівень масива або обʼєкта. І якщо там примітивні значення, то можна сказати, це "копія". Але якщо є вкладеності, то
... скопіює посилання на них, а не зробить клоновані копії.const original = {
value: 1,
nested: { deep: true },
};
const copy = { ...original };
copy.nested.deep = false;
console.log(original.nested.deep); // falseА ще
... копіює виключно перший видимий рівень. Тобто прототип, неперелічувані властивості, символи — усе піде під ніж, і ви отримаєте стерильну копію.***
Якщо дізналися щось нове — напишіть у коментарях, що саме здивувало чи стало у пригоді.
А далі — обирати вам! Про що буде наступний допис?
🔥 — Дірки в масивах: як вони зʼявляються і що ламають
❤️ — Symbol.iterator: ітерабельність під капотом
🤔 — Чи настільки різні масиви та обʼєкти?
.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥60❤43🤔23👏2
Порожнеча дивиться на тебе.
Масиви в JavaScript мають одну цікаву особливість — вони можуть бути "дірявими". Якщо дуже коротко — ми можемо явно присвоїти значення будь-якому індексу, і якщо цей індекс не є наступним після останнього значення, то утвориться розрив.
Дірка — не undefined! Хоча при звертанні до "дірки" вам і поверне undefined, насправді в самому масиві його не буде. Дірка означає повну відсутність значення за індексом, він просто не ініціалізований. Це випливає з того, що масив — це підвид обʼєкту, просто з певним інтерфейсом для впорядкування ключів.
По факту, масив з діркою, наприклад той самий
Індекс 1? Його просто немає.
Дірява поведінка
Дірки поводяться по своєму, і не завжди передбачувано. Візьмемо до прикладу масив
А тепер точнісінько такий масив, але замінимо дірку явним undefined:
Помітили різницю? Так от, map, forEach, filter, reduce, every, some просто ігнорують дірки, перестрибують їх. А for...of, for навпаки — зазирнуть у кожну дірочку.
А JSON.stringify взагалі перетворює дірки в масиві на… null.
До речі, як визначити, що це саме дірка, а не просто undefined? Перевірити наявність індекса в масиві. Якщо ключа немає, то це — дірка:
Дірка як палиця в колесі.
Така поведінка, очікувано, може призводити до багатьох дивних ситуацій, особливо при клонуванні чи порівнянні масивів. Ще більше збиватиму з пантелику той факт, що [].length віддає не фактичну кількість ключів, а "найбільший індекс + 1", що теж не додає впевнености при роботі з дірявими масивами.
Також JavaScript рушії не дуже полюбляють діряві масиви, бо робота з ними вимагає відмови від багатьох оптимізацій, які можна застосувати до безпереревних масивів. Я не буду вдаватися в деталі, лише зазначу, що це дійсно впливає і на споживання памʼяті, і на внутрішню швидкодію. Звичайно, ви не помітите різниці на масиві з десятком дірок, але якщо їх 100 000, 1 000 000, то втрати будуть відчутні.
Заштопати всі дірки!
Найочевидніша порада — не допускайте дірок. Якщо вам потрібна подібна структура, краще використати обʼєкт з власним ітератором. Якщо ж в руки потрапив такий масив, то його краще ущільнити: чи то зібрати лише реальні значення в інший масив, чи то заповнити дірки явним undefined — у будь-якому разі рушій вам подякує, а потім подякуєте і ви собі.
💬 А ви стикались із дірками в проді?
Чи, може, самі колись ненароком залишили? Поділіться досвідом у коментарях!
🔗 @babichdev
.
Масиви в JavaScript мають одну цікаву особливість — вони можуть бути "дірявими". Якщо дуже коротко — ми можемо явно присвоїти значення будь-якому індексу, і якщо цей індекс не є наступним після останнього значення, то утвориться розрив.
let arr = ['one', , 'three'];
// ['one', empty, 'three'];
arr[100] = 'value';
// ['one', empty, 'three', empty × 97, 'value']
Дірка — не undefined! Хоча при звертанні до "дірки" вам і поверне undefined, насправді в самому масиві його не буде. Дірка означає повну відсутність значення за індексом, він просто не ініціалізований. Це випливає з того, що масив — це підвид обʼєкту, просто з певним інтерфейсом для впорядкування ключів.
По факту, масив з діркою, наприклад той самий
['one', ,'three'], у обʼєктному записі виглядатиме так:{ 0: 'one', 2: 'three' }Індекс 1? Його просто немає.
Дірява поведінка
Дірки поводяться по своєму, і не завжди передбачувано. Візьмемо до прикладу масив
[1, , 3] та порахуємо квадрати його значень:[1, , 3].map(x => x * x) // [1, empty, 9]
А тепер точнісінько такий масив, але замінимо дірку явним undefined:
[1, undefined, 3].map(x => x * x) // [1, NaN, 9]
Помітили різницю? Так от, map, forEach, filter, reduce, every, some просто ігнорують дірки, перестрибують їх. А for...of, for навпаки — зазирнуть у кожну дірочку.
А JSON.stringify взагалі перетворює дірки в масиві на… null.
До речі, як визначити, що це саме дірка, а не просто undefined? Перевірити наявність індекса в масиві. Якщо ключа немає, то це — дірка:
const arr = ['one', , 'three'];
1 in arr; // false
Дірка як палиця в колесі.
Така поведінка, очікувано, може призводити до багатьох дивних ситуацій, особливо при клонуванні чи порівнянні масивів. Ще більше збиватиму з пантелику той факт, що [].length віддає не фактичну кількість ключів, а "найбільший індекс + 1", що теж не додає впевнености при роботі з дірявими масивами.
Також JavaScript рушії не дуже полюбляють діряві масиви, бо робота з ними вимагає відмови від багатьох оптимізацій, які можна застосувати до безпереревних масивів. Я не буду вдаватися в деталі, лише зазначу, що це дійсно впливає і на споживання памʼяті, і на внутрішню швидкодію. Звичайно, ви не помітите різниці на масиві з десятком дірок, але якщо їх 100 000, 1 000 000, то втрати будуть відчутні.
Заштопати всі дірки!
Найочевидніша порада — не допускайте дірок. Якщо вам потрібна подібна структура, краще використати обʼєкт з власним ітератором. Якщо ж в руки потрапив такий масив, то його краще ущільнити: чи то зібрати лише реальні значення в інший масив, чи то заповнити дірки явним undefined — у будь-якому разі рушій вам подякує, а потім подякуєте і ви собі.
💬 А ви стикались із дірками в проді?
Чи, може, самі колись ненароком залишили? Поділіться досвідом у коментарях!
І якщо було цікаво — не забудьте поширити допис або кинути лінк колезі.
.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥71❤18👏3🤔2
Виграти квиток на JavaScript fwdays'25 усього за сто гривень? Та легко!
Товариство, хто ще не придбав квиток на конференцію, але дуже хочe туди потрапити? Маєте шалену нагоду виграти один з двох Full Ticket квиточків та відвідати цю чудову подію і зустрітися з, до прикладу, Іллєю Климовим, чи Юрієм Артюхом. Ну і я десь там пробігатиму.
Усе, що треба — просто долучитися до збору на РЕБ для в/ч А3892.
Кожні 100 грн — ще один шанс виграти.
Фінальна ціль — 260 000 грн.
Посилання на банку
https://send.monobank.ua/jar/ABkKH6rr3u
Номер картки банки
4441111125077309
Переможців оберу наступної середи, 20 травня, рандомом від monobank.
@babichdev
в коментарях є фото листа-прохання
Товариство, хто ще не придбав квиток на конференцію, але дуже хочe туди потрапити? Маєте шалену нагоду виграти один з двох Full Ticket квиточків та відвідати цю чудову подію і зустрітися з, до прикладу, Іллєю Климовим, чи Юрієм Артюхом. Ну і я десь там пробігатиму.
Усе, що треба — просто долучитися до збору на РЕБ для в/ч А3892.
Кожні 100 грн — ще один шанс виграти.
Фінальна ціль — 260 000 грн.
Посилання на банку
https://send.monobank.ua/jar/ABkKH6rr3u
Номер картки банки
4441111125077309
Переможців оберу наступної середи, 20 травня, рандомом від monobank.
@babichdev
в коментарях є фото листа-прохання
🔥6❤4
Синьйор мусить знати все!
Ні. Не все.
Радше так: синьйор не має знати напамʼять увесь MDN. Як і мідл. Як і джун. Як і техлід. Взагалі, розробник не має знати всього напамʼять — це не показник експертности.
Розробка — це не контрольна робота. Це не про “знаєш або не знаєш”. Це про вміння орієнтуватися, коли стикаєшся з новим. Про вміння формулювати запит, знайти джерело, зрозуміти, перевірити, застосувати. Це — робота з невизначеністю.
Так, є база, без якої нікуди, і яка постійно змінюється. Є зони відповідальности. Є глибина, яку справедливо очікують від розробника певного рівня. Але навіть у синьйора в голові не вміщається весь Intl API, увесь Grid, або всі edge-кейси WebRTC. І це — нормально.
Найкращі розробники, з якими я працював — не ті, хто “все памʼятає”. А ті, хто не втрачає холодної голови, коли чогось не знає. Хто знає, як і де шукати. Хто не боїться питати. І хто не знецінює себе за пробіл — бо знає, що пробіл не означає порожнечу.
Коли я не знаю щось на співбесіді — це не провал. Це точка росту. Коли забуваю щось на етері — це не соромно. Це звичайний обсяг людської памʼяті, а не причина знецінювати себе.
Знання — це не інвентар, який мусить бути повним.
Це навичка працювати з невідомим.
Уміння рухатись уперед, навіть коли карти в голові ще не розкладені.
Між “я не знаю, як дізнатися” і “я не знаю, але розберусь” — ціла прірва. І справжній фахівець — це той, хто цю прірву давно перейшов.
Ти не мусиш усе знати.
Ти мусиш вміти дізнатися.
💬 А ви як ставитеся до моментів, коли чогось не знаєте?
Чи було таке відчуття, що «мусив же це знати!» — і що з ним робили?
P.S. На fwdays за 100 гривень?! Це можливо взагалі? Я кажу — так!
🔗 @babichdev
Ні. Не все.
Радше так: синьйор не має знати напамʼять увесь MDN. Як і мідл. Як і джун. Як і техлід. Взагалі, розробник не має знати всього напамʼять — це не показник експертности.
Розробка — це не контрольна робота. Це не про “знаєш або не знаєш”. Це про вміння орієнтуватися, коли стикаєшся з новим. Про вміння формулювати запит, знайти джерело, зрозуміти, перевірити, застосувати. Це — робота з невизначеністю.
Так, є база, без якої нікуди, і яка постійно змінюється. Є зони відповідальности. Є глибина, яку справедливо очікують від розробника певного рівня. Але навіть у синьйора в голові не вміщається весь Intl API, увесь Grid, або всі edge-кейси WebRTC. І це — нормально.
Найкращі розробники, з якими я працював — не ті, хто “все памʼятає”. А ті, хто не втрачає холодної голови, коли чогось не знає. Хто знає, як і де шукати. Хто не боїться питати. І хто не знецінює себе за пробіл — бо знає, що пробіл не означає порожнечу.
Коли я не знаю щось на співбесіді — це не провал. Це точка росту. Коли забуваю щось на етері — це не соромно. Це звичайний обсяг людської памʼяті, а не причина знецінювати себе.
Знання — це не інвентар, який мусить бути повним.
Це навичка працювати з невідомим.
Уміння рухатись уперед, навіть коли карти в голові ще не розкладені.
Між “я не знаю, як дізнатися” і “я не знаю, але розберусь” — ціла прірва. І справжній фахівець — це той, хто цю прірву давно перейшов.
Ти не мусиш усе знати.
Ти мусиш вміти дізнатися.
💬 А ви як ставитеся до моментів, коли чогось не знаєте?
Чи було таке відчуття, що «мусив же це знати!» — і що з ним робили?
P.S. На fwdays за 100 гривень?! Це можливо взагалі? Я кажу — так!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥112❤37👏6
Друзі, сьогодні я в гостях у Сергія Немчинського, і просто зараз розпочнеться стрим, на якому ми з ним обговоримо актуальні новини а ІТ. Про що конкретно — взагалі не здогадуюсь, але має бути цікаво )
https://www.youtube.com/live/3aBzFZjxb6w?si=dmx4xNBWdEdr1rA5
https://www.youtube.com/live/3aBzFZjxb6w?si=dmx4xNBWdEdr1rA5
YouTube
Основні ІТ-новини та тренди в Україні
🔗 Реєстрація на вебінар “Стратегія входу в ІТ у 2025: від нуля до розробника з першим комерційним досвідом”
https://go.foxminded.ua/459Uvaa
Ютуб канал Сергія Бабіча: https://www.youtube.com/@UCLRWnQw_G3kegbb4z-aRKSQ
Телеграм канал Сергія Бабіча: https:…
https://go.foxminded.ua/459Uvaa
Ютуб канал Сергія Бабіча: https://www.youtube.com/@UCLRWnQw_G3kegbb4z-aRKSQ
Телеграм канал Сергія Бабіча: https:…
🔥23❤12