Привет, Хабр!


Общаясь с коллегами, я заметил, что они незнакомы с последними возможностями CSS. Как обычно, у всех свои причины. У кого-то много повседневной рутины. Кому-то в принципе неинтересно, что нового происходит в CSS. А кто-то по привычке использует подходы десятилетней давности и ему норм.


Как фанату CSS, мне грустно. Сколько же прикольных вещей проходит мимо них. Да и их код может быть меньше, надёжнее и проще для понимания. В общем, я собрал несколько фрагментов кода, которые были популярны давным-давно, и переписал их с помощью новых возможностей CSS.


Давайте посмотрим, что я вам подготовил.


▍ Центрирование элемента с помощью свойства transform и значения translate(-50%, 50%)


Центрирование элементов всегда было камнем преткновения. Очень долго не было простого способа реализовать эту задачу. Даже на собеседованиях всегда спрашивали: «Как можно отцентрировать элемент со свойством position и значением absolute по двум осям?».


Потом появилось свойство transform, и все массово стали его использовать.


.parent {
  position: relative;
}

.parent::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

Расскажу, что тут происходит. Сначала происходит смещение элемента с помощью свойств top и left. Важно помнить, что браузеры перемещают верхний левый угол. В итоге мы получим, что он будет находиться по центру родительского элемента.


А нам нужно, чтобы в центре была середина элемента. Для этого надо сместить его в противоположную сторону на половину ширины и высоты. Тут и помогает свойство transform.


Если для него задать значение в процентах, то итоговое значение смещения браузеры будут вычислять относительно свойств width и height. В результате мы увидим, как элемент сместится в центр родительского элемента.


Сегодня уже можно сделать проще. Нам больше не надо смещать элементы с помощью свойств top и left, а следовательно, и свойства transform. Значение center для свойства place-items сразу сделает всю магию.


.parent {
  display: grid;
  place-items: center;
}

.parent::before {
  content: "";
  position: absolute;
}

Также не надо добавлять свойство position со значением relative. Поскольку свойств top и left больше нет.


▍ Стилизация элементов на основе селекторов + или ~


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


С требованиями жестить не будем. Пусть минимальная длина пароля должна быть минимум четыре символа.


<body>
  <!-- встроенная валидация отключена, потому что чаще всего её реализуют самостоятельно --> 
  <form class="form" novalidate>
    <!-- другие элементы -->
    <div class="field">
      <label class="field__label" for="password">Пароль</label>
      <input class="field__input" id="password" type="password" minlength="4" required>
      <span class="field__hint">Пароль должен быть больше 3 символов</span>
    </div>
    <!-- другие элементы -->
  </form>
</body>

Исчезновение подсказки будем реализовывать через свойство display. Будем его добавлять со значением none к элементу с классом .field__hint, если пользователь ввёл четыре и более символов.


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


.field__input:valid + .field__hint {
  display: none;
}

Только этот способ всегда вызывал проблемы. Кто-то случайно поменял порядок элементов, и код отваливался. Сегодня это можно побороть, заменив этот подход на решение с использованием псевдо-класса :has.


.field:has(.field__input:valid) .field__hint {
  display: none;
}

Теперь наш код фиг сломаешь. Ему всё равно на то, как располагаются элементы в разметке. Больше не будет неожиданных ошибок!


▍ Объявление стека системных шрифтов


В комментариях под статьёй «Как фронтендеру сделать интерфейс дружелюбнее к пользователю. Коллекция HTML/CSS лайфхаков» я нашёл код с использованием ключевого слова system-ui, когда его поддержкой была неидеальной. Этот комментарий помог мне вспомнить, что раньше был подход использования системных шрифтов.


Суть заключалась в том, что указывались все семейства шрифтов, которые используются в операционных системах по умолчанию. Назвали такой подход «System Font Stack». Было несколько вариантов реализации.


/* реализация Github */
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}

/* реализация Medium */
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue",sans-serif;
}

Сегодня поддержка ключевого слова system-ui позволяет нам отказаться от этих фрагментов кода. Оно же само говорит браузерам использовать системный шрифт. Больше подсказки не нужны!


Нам осталось просто добавить его в качестве единственного значения для свойства font-family.


body {
  font-family: system-ui;
}

Такой код пишу я. Но если вы хотите, можно добавить вторым значением sans-serif. Вдруг вам покажется такой код ненадёжным.


▍ Установка размеров с помощью свойств width и height для элементов с position: absolute или position: fixed


Несколько недель назад я проверил, сможет ли ChatGPT заменить меня. Одной из задач было сверстать модальное окно. Далее покажу, какой код написал ChatGPT для его стилизации.


.modal {
  display: none; 
  width: 100%;
  height: 100%;

  position: fixed;
  top: 0;
  left: 0;
  z-index: 1000;

  justify-content: center;
  align-items: center;

  background-color: rgba(0, 0, 0, 0.5);
}

Обращу внимание на свойства top, left, width и height. Браузеры, обработав их, расположат элемент в левом верхнем углу, растянув на всё пространство по ширине и высоте.


Супер решение, которое я лично использовал десять лет. Но его можно сократить до одной строки. Задайте значение 0 для свойства inset.


.modal {
  display: none; 
  position: fixed;
  inset: 0;
  z-index: 1000;

  justify-content: center;
  align-items: center;

  background-color: rgba(0, 0, 0, 0.5);
}

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


А также вы можете использовать свойство inset для случаев, когда используется значение absolute.


.awesome-block { 
  position: absolute;
  inset: 0;
  background-color: rgba(0, 0, 0, 0.5);
}

▍ Объявление значения для свойств margin и padding вместе со значением 0


Проводя код-ревью, я всё ещё замечаю старый подход к объявлению свойств margin и padding. Если требуется установить значение только по одной оси, разработчики вынужденно используют значение 0.


.awesome-block {
  margin: 0 auto;
  padding: 1rem 0 2rem;
}

Уже не надо так делать. Есть логические CSS-свойства. Они позволяют установить отступ только по оси.


.awesome-block {
  margin-inline: auto;
  padding-block: 1rem 2rem;
}

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


Да, логические свойства зависят от основного направления текста, которое задаётся свойством writing-mode. Но ошибка может произойти, только если вы будете использовать значения vertical-lr или vertical-rl. А это вряд ли случится — если только вы делаете интерфейс для азиатской аудитории, например, японской.


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


▍ Установка ширины блочного элемента с использованием свойства display


У меня к вам вопрос: «Как можно сделать так, чтобы браузеры рассчитывали ширину блочного элемента по контенту?».


<body>
  <div class="awesome-block">
    <span>Блочный элемент с текстом</span>
  </div>
</body>

.awesome-block {
  padding: 0.5rem;
  background-color: lightblue;
  /* что ещё тут нужно дописать? */
}

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


Скорее всего, вы вспомните, что можно поменять значение свойства display на inline-block, inline-flex или inline-grid. И вы будете правы.


.awesome-block {
  padding: 0.5rem;
  background-color: lightblue;
  display: inline-grid;
}

Без вопросов, это проверенный временем способ. Но он не всегда сработает, потому что не всегда можно менять значение свойства display. Лучше использовать ключевое слово fit-content.


Я сразу перейду к нашему примеру и добавлю свойство width со значением fit-content для элемента с классом .awesome-block.


.awesome-block {
  padding: 0.5rem;
  background-color: lightblue;
  width: fit-content;
}

А главный плюс нового решения заключается в том, что элементы сохранят своё расположение. Например, в случае с блочными элементами они продолжат располагаться в столбец. В первом решении такого не было бы.


▍ Расположение элементов в столбец с помощью свойства flex-direction со значением column


Давайте решим простую задачу. Нам нужно расположить несколько элементов друг под другом и задать между ними отступ. А-ля блок с карточками новостей. Сразу скажу, что мы исключаем решение с блочными элементами и свойством margin для отступов.


Часто я встречаю, что разработчики используют свойство flex-direction и gap.


.container {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

У меня всегда в голове вопрос: «Зачем?». Можно же просто использовать значение grid для свойства display.


.container {
  display: grid;
  gap: 1rem;
}

Это вполне рабочий приём. Так что если вам нужно расположить два элемента в столбец с отступами, то имейте в виду это решение.


▍ Заключение


Вот и всё. Я постарался показать альтернативные подходы и их плюсы. Не знаю, получилось ли хорошо, но в любом случае надеюсь, что вы нашли что-то новое для себя и захотели это использовать в своём коде.


Обязательно напишите, что я упустил, написал не так и в чём не прав. Для этого есть комментарии. А я их читаю.


Спасибо за чтение!


P.S. Помогаю больше узнать про CSS в своём ТГ-канале CSS isn't magic. Присоединяйтесь. Ссылка в профиле.


© 2025 ООО «МТ ФИНАНС»

Telegram-канал со скидками, розыгрышами призов и новостями IT ?

Комментарии (55)


  1. pnmv
    17.06.2025 09:24

    когда вижу предложение заменить одно на другое, особенно если последнее менее конкретно, встает главный вопрос - что с производительностью?


    1. melnik909 Автор
      17.06.2025 09:24

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

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


      1. pnmv
        17.06.2025 09:24

        я из другой области - пишу вам с делёкого бекенда. извините, если что.

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


        1. melnik909 Автор
          17.06.2025 09:24

          Уточните, пожалуйста, про какой пример вы говорите?


          1. pnmv
            17.06.2025 09:24

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


          1. Gary_Ihar
            17.06.2025 09:24

            давайте там где :has вместо +, если вы не против?


            1. melnik909 Автор
              17.06.2025 09:24

              Хорошо. Попробую из этого сделать статью


  1. alexzen
    17.06.2025 09:24

    Странные советы. Для центрирования display: flex намного удобнее и читаемость кода выше.


    1. melnik909 Автор
      17.06.2025 09:24

      Ни разу за 10 лет не встречал использование флексов для позиционирования элемента с position: absolute. Надо взять на вооружение!

      .parent {
        display: flex;
        justify-content: center;
        align-items: center;
      }
      
      .parent::before {
        content: "";
        position: absolute;
      }

      Вы этот способ имели ввиду?


      1. Spaceoddity
        17.06.2025 09:24

        А зачем тут вообще позиционирование? Как все модалки во всём вебе сейчас выглядят:

        .modal-bg{
        	position: fixed;
        	top: 0;
        	left: 0;
        	right: 0;
        	bottom: 0;
        	
        	display: flex;
        	justify-content: center;
        	align-items: center;
        
        	background: rgba(0, 0, 0, 0.4);
        
        	z-index: 1000;
        }
        .modal-bg__window{
        	width: 300px; /* 50%  40vw auto и т.п.*/
        }
        


        1. melnik909 Автор
          17.06.2025 09:24

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


        1. CzarOfScripts
          17.06.2025 09:24

          Для align-items я бы добавил еще safe


          1. Spaceoddity
            17.06.2025 09:24

            А ещё я flex-flow всегда прописываю ;)


  1. cp_poonam
    17.06.2025 09:24

    Really enjoyed this post! I still come across teams using older CSS methods like translate(-50%, -50%). This article is a great reminder of how far CSS has come. I’ll definitely be referencing this when updating our internal style guides. Appreciate the practical examples!


  1. sfi0zy
    17.06.2025 09:24

    Сегодня уже можно сделать проще. Нам больше не надо смещать элементы с помощью свойств top и left, а следовательно, и свойства transform. Значение center для свойства place-items сразу сделает всю магию.

    И заодно создаст побочный эффект в виде изменения логики расположения других элементов в контейнере. Главная фишка приема с transform на 50% взад состоит в том, что этот элемент ни на что не влияет. И двигать можно по мере необходимости, не только на 50%. Это очень удобно при верске "дизайнерской дичи" в рекламе. Вся визуальная фигня вокруг контейнеров с контентом просто существует в своем абсолютно позиционированном мире, и ее не нужно ничем подпирать. А place-items меняет логику для основного контента в контейнерах. Получается лишняя связь между вещами, которые не должны быть связаны. И гибкость решения страдает. Так что новый вариант хорош, но не всегда.


  1. Spaceoddity
    17.06.2025 09:24

    Блин, наверное, пройдусь по всём пунктам попозже. А пока ответ на основной тезис "Общаясь с коллегами, я заметил, что они незнакомы с последними возможностями CSS". Почему сразу незнакомы? Возможно просто стесняются юзать. Как я. Так уж исторически повелось - что у верстальщиков выработалась некоторая инерция в освоении новых фич. И не на пустом месте ;) Потому что перед юзанием каждой подобной фичи, надо сверяться c caniuse, или того хлеще - видеть приписку "*в настройках браузера надо проставить флаг...".

    P.S. Одна из немногих фич CSS, за которую я ухватился как только о ней узнал - display: contents - как же я её ждал))


    1. melnik909 Автор
      17.06.2025 09:24

      Возможно просто стесняются юзать. Как я. Так уж исторически повелось - что у верстальщиков выработалась некоторая инерция в освоении новых фич. И не на пустом месте ;)

      Мне кажется дело кроется в том, что вы не доверяете технологиям. Вы же сами об этом пишите. И вы не одиноки. Для многих CSS это черный магический ящик. Это тоже не на пустом месте случилось.

      Я пытаюсь, как-то помочь с этим справиться. Могу я немногое. Например, подсказывать куда смотреть. Это я пытаюсь делать


      1. Heggi
        17.06.2025 09:24

        До недавнего времени большинство "революционных" или просто "новых" фич (кавычки тут не зря) тупо не поддерживались большинством браузеров. Фича, которая есть хроме, не факт что есть в каком-нибудь IE или сафари. Особенно сильно с внедрением фич тормозил IE. И лучше использовать старые, проверенные способы и костыли с гарантией работоспособности, нежели идти и проверять новинки во всей куче браузеров.
        Сейчас с этим попроще, актуальных браузеров (движков) осталось 3 штуки и теперь главный тормоз на арене - сафари.


  1. Spaceoddity
    17.06.2025 09:24

    Стилизация элементов на основе селекторов + или ~

    Но суть техники о которой вы рассказываете, совсем в другом)) Это уже полноценный siblings. Тут логика переходит уже на совершенно иной уровень.

    Ну и как я говорил ранее - настолько крутые фичи пока что откровенно ссыкотно юзать)) Лучше перестраховаться))

    Да и потребность в + и ~ не исчезнет (особенно +).


    1. melnik909 Автор
      17.06.2025 09:24

      Где бы вы использовали + и ~?


      1. Spaceoddity
        17.06.2025 09:24

        Допустим, если сразу после <p> идёт <ul>.


        1. melnik909 Автор
          17.06.2025 09:24

          Согласен


      1. dom1n1k
        17.06.2025 09:24

        Самое банальное:

        .some-container p + p {
            margin-top: 0.5em;
        }

        Можно, конечно, все абзацы завернуть в какой-то флекс и прописать гэпы, но зачем слишком привязываться к контексту?


        1. melnik909 Автор
          17.06.2025 09:24

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


    1. Safort
      17.06.2025 09:24

      Ну и как я говорил ранее - настолько крутые фичи пока что откровенно ссыкотно юзать)) Лучше перестраховаться))

      Вот сложно мне понять в чём перестраховка и боязнь работы, например, с :has? Он поддерживается с 2022 года в большинстве браузеров, с ним код более гибкий. Чего бояться?


      1. Spaceoddity
        17.06.2025 09:24

        Слушайте, ну ладно бы у вас дата регистрации недавняя была)) Но вы же должны помнить "браузерные хаки", например? Кроссбраузерность? Понимаете к чему я клоню?

        А если юзер не обновлял браузер с 2022? А если у него какой Edge? Мне вот довелось поддерживать даже IE6, потому что "эти 1.5% - тоже наши клиенты"... И ладно бы дело тут обошлось каким graceful degradation, дык нет - в обсуждаемом примере легко может поломаться вообще вся вёрстка!

        с ним код более гибкий

        Очень сомнительное утверждение. Длинные (а в нашем случае ещё и не самые очевидные) цепочки селекторов, как правило, ухудшают читаемость...


      1. dom1n1k
        17.06.2025 09:24

        Большинство - понятие очень растяжимое.

        Вот открыл я сейчас caniuse, и он показал мне поддержку :has в ~93%.
        Много это или мало? Ну смотря для чего. Есть свойства декоративные, которыми можно жертвовать, а есть функциональные.

        Условный border-radius можно спокойно юзать с поддержкой 70, да хоть бы даже и 50 процентов - ну не скруглятся у кого-то кнопки, но всё остальное ведь работает.
        На :has обычно вешают что-то более функционально-значимое, что было бы неприятно потерять. В этом случае 93% выглядят чем-то пограничным - вроде и нормально, но некоторая тревога остается.

        А вот например, для базового лейаута надежность 93% - недопустимо низкая. Мы не должны позволять себе мысль, что аж 7% юзеров увидят полностью сломанную страницу, и это типа нормально. Либо нужно использовать что-то более надежное (процентов 97+), либо нужно подумать о фолбеках. Но иногда бывает так, что фолбек полностью закрывает потребность, и тогда непонятно зачем нужен прогрессивный вариант.

        Короче, использовать можно, но аккуратно и подпирая там, где может упасть.
        А вот эту беззаботность (ой да работает у меня в хроме уже везде, че там париться) старые верстальщики обычно не любят. Хотя нельзя не признать, что ситуация с браузерами сейчас действительно намного лучше, чем 10 лет назад.


        1. melnik909 Автор
          17.06.2025 09:24

          А вот например, для базового лейаута надежность 93% - недопустимо низкая. Мы не должны позволять себе мысль, что аж 7% юзеров увидят полностью сломанную страницу, и это типа нормально. Либо нужно использовать что-то более надежное (процентов 97+), либо нужно подумать о фолбеках. 

          У вас крутой посыл, но я с ним не соглашусь наполовину. Как альтруист и любитель делать "для пользователей" я согласен с вами. Но верстка это один из этапов конвейера.

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

          В твоих проектах 1% процент пользователей может быть 2 человека, а у нас это 200 000 людей.

          Вот если разработчик работает там, где всё равно на 1% пользователей, потому что это фактически мало клиентов, то ему даже не дадут думать о этих людях, потому что:

          1. Его коллеги не будут думать, потому что руководству такого количество клиентов не интересно

          2. Разработчик будет поставлен перед выбором: либо не делаешь, либо делаешь в свободное время

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

          На это можно посмотреть так. Люди не хотят вкладываться в то, что сомнительно по прибыли. В случае с пользователями скринридера это носит негатив, а в случае с условным :has позитив, потому что браузеры не поддерживающие эту функцию подавляющее меньшинство. Поэтому можно "забить".

          Последняя субъективная мысль. В текущем процессе никогда не будет ПО, которое будет учитывать интересы всех пользователей. Может AI что-то в этом изменит.


          1. dom1n1k
            17.06.2025 09:24

            Понятно, что я упрощаю. Специфику конкретной ситуации никто не отменял. И конечно, смотрят на аудиторию, цифры и вот это всё.

            Но хочу, чтобы за цифрами не потерялась вот эта мысль:

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

            По опыту, не так уж редки ситуации, когда "старое" решение ну действительно ничем не хуже "нового". Как пример - обсуждаемая тут попытка заменить плюс на :has.
            В чем преимущество нового решения, кроме того, что оно новое? Да вот как будто ни в чём. Работает как-то лучше? Нет. Читается лучше? Точно нет. Работает быстрее? Почти наверняка нет. Стоит дешевле? Наоборот, дороже, потому что возможно понадобится написать @supports. Тогда зачем оно (в данном случае) нужно?

            А вот гриды умеют то, что старые раскладки либо вообще никак, либо нужно как-то извратиться. Или тот же :has в иных ситуациях даёт то, что иначе никак не получить или костыли будут в три этажа.

            То есть новизна сама по себе - недостаточный фактор. Должны быть какие-то конкретные преимущества для UX или DX.


            1. melnik909 Автор
              17.06.2025 09:24

              Во-первых.

              Тогда зачем оно (в данном случае) нужно?

              Плюс has в том, что он убирает необходимость следить за порядком элементов. Мой пример был написан, как "намек". В реальности проблема следующая.

              Разработчики используют + в разных визуальных задачах, связанных с элементами формы . Поскольку они читают, что нужен label, они его хотят добавить. Поскольку они используют +, они могут добавить label только после input.

              А тут мы встречаем нюансы озвучивания в скринридерах. При переключении стрелками и табом пользователь по разному услышит информацию. Ему нужно дополнительно разбираться в озвучке подсказок. Это если говорить без углубленных деталей.

              Во-вторых.

              Должны быть какие-то конкретные преимущества для UX или DX.

              DX очень субъективное поле. Я сюда не хожу. Но повторюсь, что на половину согласен с вами.


  1. ImagineTables
    17.06.2025 09:24

    Часто я встречаю, что разработчики используют свойство flex-direction и gap. У меня всегда в голове вопрос: «Зачем?».

    Чтобы подчеркнуть одномерность. Код ведь читают в первую очередь люди, а уже потом — браузеры.

    А вообще, как сказал один гуру разработки браузеров, страшный бардак у нас в CSS — несколько конкурирующих моделей позиционирования свалены в кучу.

    Как пример проявления этого бардака — гриды не поддерживают флюидность. Конечно, для колонки флюидность, чаще всего, не нужна, но если вдруг понадобится, гридом так легко её не сделать. (Или я просто не знаю способа — для придания флюидности гриду у меня написан достаточно корявый миксин).


    1. dom1n1k
      17.06.2025 09:24

      Нельзя ли развернуть про флюидность подробнее?


      1. ImagineTables
        17.06.2025 09:24

        // Generates a fluid grid, emulating flex behavior with
        // flex-basis: @cell-size, flex-grow: 0 and flex-shrink: 1.
        .fluid-grid(@cell-size, @gap, @column-count)
        {
        	display: grid;
        	width: min(100%, (@column-count * @cell-size + (@column-count - 1) * @gap));
        	grid-template-columns: repeat(@column-count, 1fr);
        	// By default, both gaps are equal. Override row gap in-place, if needed.
        	gap: @gap;
        }
        

        Если кто-то знает способ лучше, подскажите.


        1. dom1n1k
          17.06.2025 09:24

          Если можно, сделаем шаг назад и вернемся к постановке задачи.
          Какое конкретно поведение вы называете флюидностью?
          И что именно не работает?


          1. ImagineTables
            17.06.2025 09:24

            В комментарии, вроде, постановка задачи исчерпывающе объяснена. Есть двухмерная структура, и поэтому она grid. Но по одному из измерений (в данном случае, по ширине) нужно поведение как у флекс-контейнера с flex: 0 1 @basis; (флекс-элементами являются колонки).

            Я не нашёл, как такое поведение задаётся напрямую, пришлось городить вышеприведённый костыль. Если вы знаете как, подскажите. Я всегда рад заменить костыль родными встроенными средствами, если вдруг оказывается, что я их проглядел. А если нет, это пример того, что каждая модель что-то умеет лучше других. И придётся и дальше смешивать их все, если только не появится 15-я по счёту модель, которая точно будет лучше и универсальнее.


            1. dom1n1k
              17.06.2025 09:24

              Да, я увидел эти флекс-свойства, но не совсем понял, зачем может понадобиться имитировать их буквально.
              Если нужно просто несколько одинаковых колонок, то почему не работает обычный grid-template-columns: repeat(@column-count, 1fr)? Плюс, при необходимости, ограничить общую ширину контейнера через max-width.
              Непонятно, зачем там вообще фигурирует размер колонки @cell-size, если они равные? Или они не равные и предполагается им потом индивидуально менять ширину?
              Пока что этот миксин выглядит для меня как усложнение на ровном месте. Возможно, я что-то недопонял, поэтому и уточняю.


    1. Spaceoddity
      17.06.2025 09:24

      А вообще, как сказал один гуру разработки браузеров, страшный бардак у нас в CSS — несколько конкурирующих моделей позиционирования свалены в кучу.

      Открою вам секрет - это никакой не гуру)) Если уж он путает позиционирование (это то, которое имеет position, отличное от static) и модели раскладки (флексбоксы, гриды).

      Как пример проявления этого бардака — гриды не поддерживают флюидность.

      Я тоже не понимаю что вы подразумеваете под "флюидностью"... "Резиновость" или что? В любом случае гриды в это умеют ;) Потому что это двухмерная модель раскладки (в отличие от одномерного флексбокса).

      Ну перетекание контента из одной колонки в другую на них не сделать. Поэтому есть ещё модель - columns называется.


      1. ImagineTables
        17.06.2025 09:24

        Он в одного написал движок браузера с сотнями миллионов юзеров. Для меня достаточно, чтобы считать его гуру. И насколько я понял, для него «позиционирование (то, которое имеет position, отличное от static)» и «модели раскладки» — это всё конкурирующие способы представления. А ему приходится их все поддерживать, поэтому он и называет эту ситуацию бардаком.


        1. Spaceoddity
          17.06.2025 09:24

          Согласен, некорректно выразился насчёт "гуру". Т.е. я не знаю насколько хорош тот браузер, но то, что концепты CSS ему не совсем очевидны - это вполне нормально. Я вот тоже далеко не всё сразу впитал...

          И я прекрасно понимаю вашу мысль - я как-то полюбопытствовал - а как стилизуют интерфейсы "нативщики"?.. ;) Конечно им все эти концепты представления кажутся избыточными)) Но это инерция мышления. Это веб! Тут нет полиграфических полос, жёстко заданных размеров экрана гаджета... Т.е. всё это в том числе может быть, но основной упор в вебе - на адаптивные интерфейсы, которым плевать на то, какое у тебя устройство вывода - они должны быть максимально универсальными! И вот тут-то порой оказывается, что всего этого "зоопарка способов представления" даже недостаточно))


          1. ImagineTables
            17.06.2025 09:24

            а как стилизуют интерфейсы "нативщики"?

            Да я сам нативщик. В смысле, я не тащу абсолютно всё в Электрон, чтоб оно зверски тормозило. Бизнес-логику, интеграцию с ОС, файловый IO — всё это я пишу на C++, а в будущем планирую писать на Rust'е.

            Но UI — строго на HTML/CSS. А как иначе? Всякие WAI ARIA, поддержку контрастности, механизмы для 100% поддержки клавиатуры (например, стилизации :focus-visible и перенаправление клавиатурных ивентов), адаптивность и т.д. — самому с нуля писать? Да ну нафиг. Как сказал тот же гуру (опять же, в моём пересказе, в соответствии с тем, как я его понял): если вы сегодня делаете UI не на HTML, то вы или миритесь с крайней ограниченностью вашего UI-бэкенда, или пишете свою гордую, ни с чем не совместимую реализацию HTML ;)


            1. Spaceoddity
              17.06.2025 09:24

              Но UI — строго на HTML/CSS. А как иначе?

              Ну у Андроида там своя технология дефолтная, например. На сях там ведь свои гуишные либы... Ну и для всего этого CSS, разумеется, кажется избыточным. А как по мне - "мастхэв" и едва ли не главный "вин" IT-отрасли ;)


              1. ImagineTables
                17.06.2025 09:24

                Ну, под Андроид есть webview, а остальное можно так же, как на писи. В смысле, бизнес-логику, интеграцию и IO пишем на нативной джаве (в особо замороченных случаях — на плюсах через NDK). Правда, сделан этот webview пре-по-хаб-ней-ше. Если сравнивать с Internet Explorer, например.Там webview (WebBrowser Control) позволял через COM оседлать весь DOM. Получать доступ к списку узлов и свойств, через нативный колбек-интерфейс подписаться на любой DOM event и т.д. А в Андроиде мне пришлось городить чудовищные костыли.

                Я подозреваю, это было сделано специально, как раз чтобы побудить программистов использовать ихнюю «свою дефолтную технологию». К счастью, в наши дни можно сбандлить приложение с настроенным движком. И даже есть выбор между двумя известными и одним шустрым ))


  1. gun_dose
    17.06.2025 09:24

    У вас в примере по + и ~ альтернативный код через has выглядит длинее и более сложный доя восприятия. Вообще, псевдоселектор :has - одно из лучших нововведений последних лет, но пример его использования у вас совершенно бестолковый


  1. PbIXTOP
    17.06.2025 09:24

    Странное решение для модального окна, когда давно уже есть dialog


    1. strokoff
      17.06.2025 09:24

      Зашел оставить аналогичный комментарий) странно видеть в статье про современные подходы, костыли с z-index:100000


      1. Spaceoddity
        17.06.2025 09:24

        А почему z-index является костылём? В чём его "костыльность" проявляется?))


        1. strokoff
          17.06.2025 09:24

          Ну просто dialog рисуется и так в top layer который уже над всем контентом и на фоне наличия такой механики z-index задранный до больших значений выглядит как устаревший полифил/костыль. Проблемки у индекса могут начаться если понадобится накладывать одну модалку над другой или еще както перекрывать. У диалог элемента нет проблем чтобы в диалоге показать еще один диалог. (Нарример диалог может выступать как попап внутри модалки) в целом я описываю edge кейсы но все равно, проблем с ними у элемента dialog значительно меньше


          1. Spaceoddity
            17.06.2025 09:24

            Ну просто dialog рисуется и так в top layer который уже над всем контентом

            Ну вот вам с ходу "кейс" - а если не надо чтобы он был над всем контентом? Если надо, чтобы некоторые слои были всё-таки "выше" него?

            z-index задранный до больших значений выглядит как устаревший полифил/костыль

            Ерунда! Какая разница - какое там значение проставлено (ну кроме ограничений integer)? Суть этой методы в возможности использования слоёв. Всё. И ничуть она не устарела. Да, где-то (даже частенько) можно обойтись и без него, но вполне актуальная техника.

            И я не про <dialog>, я именно про z-index.

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

            Это не проблемки z-index. Это проблемы непонимания работы контекста наложения. Согласен, что порой этот контекст бывает неочевиден - но технология-то тут при чём?


            1. strokoff
              17.06.2025 09:24

              Кейса когда модальное окно показывается под контентом я не встречал за 18лет разработки, ваш аргумент мягко говоря из области фантастики. Само определение модального окна это элемент перекрывающий интерфейс и блокирующий работу с ним до момента пока действия в модальном окне не будут выполнены. Как пример алерт нативный или confirm вам. А если модальное окно не блокирует, а встраивается в интерфейс, это уже попап.

              В остальном ваш комментарий просто как наброс на вентилятор. Пользуйтесь z-index на здоровье.


              1. Spaceoddity
                17.06.2025 09:24

                Т.е. зашёл, набросил насчёт "костыльного z-index", попытался съехать с темы подменяя термины "dialog" и "модальное окно", затем прочёл краткую лекцию "Что такое модальное окно? Зачем оно нужно? Чем отличается от попапа?" (о которой его никто не просил), насрал минусом, но "набрасываю на вентилятор" при этом я?

                Всё понятно. Вопросов больше не имею.


                1. strokoff
                  17.06.2025 09:24

                  Элемент <dialog> зачастую используется в качестве модального окна - где тут подмена понятий? Еще этот элемент может служить в роли попапа. Я обрисовал вам отличие модалки от попапа чтобы отмести ваши аргументы фантастические про модалки которые появляются под частью контента.

                  Вы имеете право ставить минусы комментариям которые вам не по душе (ну или срать минусами на вашем языке)

                  Так вот возвращаясь к сабжу что z-index устаревший подход для модальных окон - это действительно так, напомню, что ранее (да и сейчас некоторые типа вас) стремятся из-за этого костыля еще располагать элемент модалки (в вашем случае div тег видимо) около закрывающего тега body, чтобы избегать наложения контента. У элемента <dialog> кстати нет такой необходимости держать его около закрывающего тега body.


  1. Metotron0
    17.06.2025 09:24

    Почему я использую flex, а не grid, когда располагаю элементы один под другим с фиксированным зазором — флексы появились раньше, какое-то время я ещё не использовал гриды, а потом стал использовать их с осторожностью, да и во всех статьях было "гриды — это не замена флексу, это дополнение", поэтому и закрепилось "не меняет флексы на гриды, где не нужна прям сетка".

    В статье неплохо бы указать, что place-items и inset — это сокращения для других, известных всем свойств.

    На счёт применения нового: в этом месяце оказалось, что у менеджера Windows 8, поэтому использование subgrid сломало у него вёрстку. Хорошо, что таких мест было мало, я просто добавил @supports(). Но задумался над тем, правильно ли я использую сабгриды на внутреннем сайте для гос. службы. Вроде, пока не жалуются.

    Узнал про anchor-name, но так как Firefox его ещё не поддерживает, начну применять года через два, если ещё буду во фронтенде.


    1. dom1n1k
      17.06.2025 09:24

      Кстати, насчет флексов и гридов. У меня сложилось ощущение, что многие фронты концепцию basis/shrink/grow любят и понимают лучше (или думают, что понимают, потому что там на самом деле много нюансов), чем концепцию 1fr - хотя казалось бы, что может быть проще и естественней?


      1. Metotron0
        17.06.2025 09:24

        Недавно я понял, что неправильно понимаю shrink-grow, потому что не смог задать нужную пропорцию =) А fr — это ж нормированные размеры. Если кто-то 1fr, то остальные считаются от него. Согласен, это проще.


  1. xeleos
    17.06.2025 09:24

    Какое-то у меня ощущение, что центрирование через transform таким образом не заменить в некоторых случаях.. но возможно я ошибаюсь. В одном месте и правда получилось, но появились графические артефакты с краями. Видимо последствия замены flex на grid.