Найти в Дзене
✨ Опубликовали результаты State of CSS 2024 Казалось, что только недавно писал о State of JS 2023 (в конце июня 😱 как быстро время летит), а тут уже вышел CSS. Пробежимся по самому интересному. Для тех, кто не курсе что это вообще такое. State of CSS - это ежегодный опрос разработчиков со всего мира о последних тенденциях CSS Фичи: ❤️Фильтр-эффекты (blur(), contrast() и подобные) набирают популярность и стали самыми используемыми функциями в этом году. ❤️:has() оказался на втором месте (хотя мне за весь год ни разу не пришлось его использовать). ❤️:aspect-ratio использовали в последнее время? А он, оказывается, на 4-м месте. Библиотеки: ❤️Tailwind CSS занимает заслуженное первое место. ❤️Bootstrap держится на втором. Его еще много лет никто не сможет сместить. ❤️Ant Design делит 3-е место с Materialize CSS. Что удивило, так это Vuetify на 19-м (❗️) месте. Мне казалось, что он должен был быть в числе лидеров. CSS-in-JS: Ничего удивительного: CSS-модули идут вровень со Styled Components и занимают первое место. Pre/Post процессоры. Здесь наблюдается интересная тенденция. Ванильный CSS, благодаря новым фичам, значительно обогнал Less и Stylus, что не может не радовать. ❤️Sass/SCSS — первое место, вопросов нет. ❤️PostCSS — второе. ❤️Ванильный CSS. ❤️Less. ❤️Stylus. Ожидаемый функционал. Самое интересное, как по мне: ❤️Миксины. Думаю, было бы логично их добавить в CSS. ❤️Conditional Logic. Сомнительно, конечно. Такой функционал точно нужно будет использовать с умом, чтобы не "выстрелить себе в ногу" и не запутаться в условиях. ❤️Masonry-шаблон. Кто не знает, был (и существует) раньше такой плагин, который выстраивал сетку, как в Pinterest. Это очень полезная фича, и я был бы рад ее добавлению. ❤️Обращение к родителю. Тоже полезный функционал, дайте две! ❤️Nesting. То, к чему мы уже привыкли, сообщество просит добавить на базовый уровень. ❤️Функции. Тема тоже актуальна, берем! И завершить можно хорошими новостями: Conditional Logic, миксины и Masonry-шаблоны уже взяты в работу, но неизвестно, на какой стадии разработки они находятся. Как тебе результаты? Все было ожидаемо или что-то удивило? А что бы ты хотел увидеть в обновлениях CSS? Может, что-то нужно убрать вообще? Ссылка на источник #css #dev
1 год назад
🔥 Жаркий спор по теме Masonry в CSS Как писал выше, CSS получает новый функционал, с помощью которого можно будет создавать сетки по типу Pinterest. Но из-за дебатов между командами WebKit и Chrome релиз задерживается. Решается вопрос о том, как должен выглядеть синтаксис. Вырисовывается классическая картина с двумя стульями: ❤️Добавить свойство display: masonry. Этот вариант предлагает команда Chrome. По мне, так это логичное и лаконичное решение. Однако возникают сложности на адаптиве. Представьте, что у вас сетка построена на flex/grid со своими дочерними свойствами (например, flex-direction и т.д.). Но на каком-то из разрешений вам понадобится использовать display: masonry. Тогда нужно будет снова писать "пачку" дочерних настраиваемых свойств для masonry-сетки. Это уже не так радужно и выглядит громоздко. ❤️Добавить свойства в спецификацию grid. Команда WebKit предлагает добавить свойство collapsed для правил grid-template-rows и grid-template-columns. В этом случае вы получаете всегда grid-сетку с возможностью "свитчить" раскладку, не меняя представление. Но это также добавляет новое значение, что только усложнит настройку сетки. Как итог, пока не понятно, в каком виде это будет выглядеть на этапе релиза, но мы можем повлиять на решение и почувствовать силу демократии, приняв участие в открытом issue от W3C. На какой стороне вы? Какой из предложенных вариантов вам больше нравится? Ставь 🔥 - 1 вариант Ставь ❤️ - 2 вариант Ставь 👍 - флексами рулили и будем разруливать. Не нужон нам этот Masonry #css #dev #news
1 год назад
🔥 Боль работы с JS объектом Date закончится в этом году. В 2024 году JavaScript получил много обновлений и новых функций, которые находятся на 3 и 4 стадии: ❤️ 3 стадия - Функция принята, но ещё рассматривается как проект и может значительно измениться. Тем не менее, в конечном итоге её включат в стандарт, за исключением маловероятных причин ❤️4 стадия - Функция одобрена и находится на стадии валидации. Изменения больше не запрашиваются, кроме необходимых доработок, выявленных при тестировании Сегодня рассмотрим Temporal API — глобальный объект, который улучшает работу с датой и временем. Одна из его особенностей — использование отдельных классов для даты и времени. На данный момент Temporal API находится на 3 стадии. Несколько полезных методов и их API: ❤️ Temporal.Now - предоставляет методы для получения текущего времени и даты. Temporal.Now.instant(): Temporal.Instant - возвращает текущее системное время. Temporal.Now.timeZoneId(): string - возвращает текущую системную тайм-зону. Temporal.Now.zonedDateTimeISO(timeZone: object | string = Temporal.Now.timeZone()) : Temporal.ZonedDateTime - возвращает текущие дату и время в текущем часовом поясе в формате ISO. Temporal.Now.plainDateISO(timeZone: object | string = Temporal.Now.timeZone()) : Temporal.PlainDate - возвращает текущую дату в текущем часовом поясе в формате ISO Temporal.Now.plainTimeISO(timeZone: object | string = Temporal.Now.timeZone()) : Temporal.PlainTime - возвращает текущее время в текущем часовом поясе в формате ISO Temporal.Now.plainDateTimeISO(timeZone: object | string = Temporal.Now.timeZone()) : Temporal.PlainDateTime - возвращает дату и время вместе. Приведу несколько примеров: Temporal.Now.instant(); // => 2024-10-27T16:12:31.894551894Z Temporal.Now.zonedDateTimeISO(); // => 2024-10-27T21:13:09.095589095+05:00[Asia/Yekaterinburg] Temporal.Now.plainDateISO()); // => 2024-10-27 ❤️Temporal.Instant - предоставляет фиксированную точку во времени ("exact time") без учёта календаря и местоположения. Примеры: instant = Temporal.Instant.from('2020-01-01T00:00+05:30'); // => 2019-12-31T18:30:00Z instant.epochNanoseconds; // => 1577817000000000000n // `Temporal.Instant` не имеет свойств зависящих от часового пояса или календаря instant.year; // => undefined zdtTokyo = instant.toZonedDateTimeISO('Asia/Tokyo'); // => 2020-01-01T03:30:00+09:00[Asia/Tokyo] zdtTokyo.year; // => 2020 zdtTokyo.toPlainDate(); // => 2020-01-01 ❤️Temporal.PlainDate - календарная дата, не связанная с определённым временем или часовым поясом. По такому же принципу работают Temporal.PlainTime, Temporal.PlainDateTime, Temporal.PlainYearMonth и Temporal.PlainMonthDay. Примеры: const date = Temporal.PlainDate.from({ year: 2025, month: 1, day: 3 }); console.log(date.year); // => 2006 console.log(date.inLeapYear); // => false console.log(date.toString()); // => '2025-01-03' ❤️Temporal.Duration - представляет временной отрезок. Его можно использовать для арифметики с датами или для вычисления разницы между временными объектами Примеры: const duration = Temporal.Duration.from({ hours: 999, minutes: 59 }); console.log(duration.total({ unit: 'second' })); // => 3599940 console.log(duration.total({ unit: 'minute' })); // => 59999 console.log(duration.total({ unit: 'hour' })); // => 999.9833333333333 Прикрепленные скрины: 1 - Объектная модель 2 - Соотношение между типами в строке Temporal 🧐 Как вы думаете, облегчит ли этот глобальный объект работу с датой и временем или все же нет? 🧐 Будете ли использовать Temporal вместо Date, когда он будет доступен и безопасен в разработке? Буду рад любой обратной связи (коммент, реакция) ❤ @aleksandr_frontend
1 год назад
👩‍💻 Zod. Основные преимущества и неочевидные кейсы использования. Zod — это TypeScript библиотека для валидации и создания схем данных, позволяющая определять строгие типы на этапе разработки. Она значительно упрощает управление типами и обеспечивает безопасность данных в приложениях. В отличие от других решений для валидации данных, Zod написан на TypeScript и позволяет использовать строгую типизацию как на этапе компиляции, так и на этапе выполнения. 🔅 Для простых структур можно задать валидацию буквально в одной строке: const userSchema = z.object({ name: z.string(), age: z.number(), email: z.string().email() }); 🔅 Одним из ключевых преимуществ является автоматическая генерация TypeScript типов из схем Zod. Это избавляет от необходимости дублировать логику валидации и типизацию данных: const user = userSchema.parse({ name: "Aleksandr", age: 31, email: "aleksandr@google.com" }); type User = z.infer<typeof userSchema>; // { name: string, age: number, email: string } 🔅 Zod также поддерживает продвинутые методы валидации: асинхронную валидацию, пользовательские валидаторы и возможность задавать условия на основании других значений в объекте: const passwordSchema = z.string().min(8).max(20); const customSchema = z.object({ password: passwordSchema, confirmPassword: z.string().refine( (value, context) => value === context.parent.password, { message: "Пароли должны совпадать" } ) }); 🔅 Композируемость. В Zod схемы можно легко комбинировать и расширять: const baseUserSchema = z.object({ name: z.string(), age: z.number().min(18), }); const adminSchema = baseUserSchema.extend({ isAdmin: z.boolean(), }); Теперь, когда мы вспомнили/познакомились с основами работы с Zod, можно перейти к неочевидным и полезным вариантам использования. 🔥 Валидация данных с API. Zod идеально подходит для валидации данных, полученных с внешних API. Это помогает избежать ошибок при работе с неподтвержденными данными, особенно если API меняет свою структуру. const apiResponseSchema = z.object({ data: z.array(z.object({ id: z.number(), title: z.string(), })) }); fetch("/api/posts") .then(response => response.json()) .then(data => { const result = apiResponseSchema.safeParse(data); if (!result.success) { console.error("Ошибка. Неподдерживаемый тип response: ", result.error); } }); 🔥 Конфигурации приложений. Zod можно использовать для строгой валидации конфигурационных файлов (например, .env). Это гарантирует корректность настроек на разных окружениях и помогает находить ошибки до запуска приложения: const configSchema = z.object({ PORT: z.string().regex(/^\d+$/).transform(Number), DATABASE_URL: z.string().url(), }); const config = configSchema.parse(process.env); 🔥 Валидация сложных форм. Скорее всего, вы это уже использовали, но если для кого то в новинку, то будет крайне полезно. В комбинации с React или другими библиотеками Zod помогает создавать более надежные интерфейсы с минимальными усилиями: const formDataSchema = z.object({ fields: z.array(z.object({ label: z.string(), value: z.union([z.string(), z.number()]), })) }); А какие кейсы вы встречали, где можно бы было применить Zod и улучшить приложение? Буду рад узнать и обсудить другие варианты применения библиотеки. #javascript #dev
1 год назад
❔ Как подружить вкладки и окна с помощью Broadcast Channel API Иногда возникает необходимость создать канал связи между вкладками, окнами или iframe в рамках одного приложения. Используя данное API, можно закрыть несколько полезных пунктов, как минимум: ✔️ Улучшение UX. ✔️ Повышение безопасности (в некоторых случаях). ✔️ Уменьшение вероятности возникновения багов. Рассмотрим на примере. Представим, что мы в интернет-магазине добавили несколько товаров в корзину и решили следующий товар открыть в новой вкладке, чтобы почитать о нем более подробно. Но в новой вкладке у нас пустая корзина (добавление/удаление товаров не связано с бэкендом). Как раз для такой ситуации, как синхронизация корзины между вкладками, нам и поможет Broadcast Channel API. 1️⃣ Добавление товара в корзину. Создадим новый канал и будем отправлять в него сообщение при каждом добавлении товара в корзину: const cartChannel = new BroadcastChannel('cart-sync'); function addToCart(item) { // Логика добавления товара в корзину const cart = getCartFromLocalStorage(); cart.push(item); saveCartToLocalStorage(cart); // Отправка сообщения другим вкладкам cartChannel.postMessage({ type: 'CART_UPDATED', cart }); } 2️⃣ Обработка изменений в других вкладках. Для корректной работы в других вкладках мы подписываемся на сообщения канала cart-sync и следим за каждым новым сообщением: cartChannel.addEventListener('message', (event) => { if (event.data.type === 'CART_UPDATED') { // Обновление корзины в текущей вкладке updateCartUI(event.data.cart); } }); function updateCartUI(cart) { // Логика для отображения актуального состояния корзины console.log('Корзина обновлена:', cart); } 🙂 Вот и все. Теперь у нас есть корзина, которая живет в своем канале и на которую можно подписываться для обновления в контексте браузера. ❗️ Не забываем также учитывать ограничение — это работает только на одном same origin. Какие есть альтернативы? Вижу только 2 варианта — сокеты или long-polling. Если есть какие-нибудь еще, в разрезе данной задачи — напиши в комментарии, пожалуйста, будет интересно обсудить. #dev #javascript
1 год назад
Если нравится — подпишитесь
Так вы не пропустите новые публикации этого канала