Организация отступов в верстке (margin/padding)

Цель этой статьи не усложнить простые вещи, а акцентировать внимание на известных стандартах, о которых почему-то забывают. Важно соблюдать осмысленную структуру во всех аспектах верстки, и не менее важно придерживаться ее в отступах. И одним из основных принципов верстки является гибкость. А именно, возможность легко вносить какие-либо изменения и ничего при этом не сломать. Правильное обращение с margin и padding играет очень большую роль в этом деле.

Ниже перечисленные принципы выполняются в среде позиционирования элементов на странице. В элементах декора тоже выполняются. Но не так категорично.

Основные принципы:

  1. Отступы идут от предыдущего элемента к следующему.
  2. Отступ задается последнему возможному элементу в доме.
  3. Отступы нельзя задавать для независимых элементов ( БЭМ блок ).
  4. У последнего элемента группы, отступ обнуляется (всегда).

Отступы идут от предыдущего элемента к следующему.


margin(ы) задаются от предыдущего элемента к следующему, от первого ко второму, сверху вниз, слева направо.



Это значит.что такие свойства как margin-left и margin-top не используются (не без исключений). С padding все немного наоборот (кроме того, что он используется для, декоративных целей, увеличения области ссылки и т.д.). Когда блоку нужен отступ сверху или слева, он его получает за счет padding-top и padding-left родителя.





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

Отступ задается последнему возможному элементу в доме


margin(ы) задаюся только между соседними элементами дом дерева.

В примере 3 списка, в следующей структуре:

<section class="main-section">
  <div class="main-section__item">
    <div>
      <ul>
        <li><a href="">Далеко-далеко, за словесными.</a></li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
      </ul>
    </div>
  </div>

  <div class="main-section__item">...</div>

  <div class="main-section__item">...</div>
</section>



Не за счет дочерних элементов, а за счет соседних делается отступ.



В этой ситуации .main-section__item и является последним возможным, кому можно задать отступ, чтоб разделить списки. Такого же эффекта можно добиться, если задать отступ диву, списку, лишке, ссылке, но это будет не правильно.

Этот пример довольно простой. Но если представить на много большую вложенность, где кто-то намусорил отступами, когда какие-то маргины схлопываются. а какие-то суммируются с падингами.


<section>
  <h1>headline in a section of seven words</h1>
</section>

Если взять пример с заголовком, и нужно сделать отступ для заголовка сверху. то последний элементом будет section и для него задается padding-top, margin(ы) которые стоят по дефолту всегда нужно обнулять.



Самая простая причина, по которой стоит придерживаться данного принципа, это чтоб было проще найти отступ в будущем, либо вам, либо тому, кто будет в дальнейшем работать с вашей версткой. Это если говорить про удобство.

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

Отступы нельзя задавать для независимых элементов ( БЭМ блок )


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

Если нужно сделать блоку отступ. Без ущерба это делается с помощью:

  • Наследование через элемент (если вытащить этот блок с элемента, отступа не будет, и его можно будет просто разместить в другом месте).
  • Добавление класса (можно сделать блок элементом).
  • Обертка (как блок, у которого роль, только в позиционировании).

.block__item > .block { margin-right: 10px; }

.block.block__item { margin-right: 10px; }

.block-wrap > .block { margin-right: 10px; }

У последнего элемента группы, отступ обнуляется (всегда)


Возьмем для примера список и изображение.
<ul>
  <li><a href=""></a></li>
  <li><a href=""></a></li>
  <li><a href=""></a></li>
  <li><a href=""></a></li>
</ul>

<img src="" alt="">

Это горизонтальное меню и логотип (который почему-то справа).

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





Для последней li отступ обнуляется. И отступ делается между соседними элементами ul и img. О чем говорилось во втором принципе.

Возьмем другой пример:

<aside class="blog-preview">
  <div class="blog-preview__item">
    <article class="preview-item">
      <h3 class="preview-item__title">...</h3>
      
      <p class="preview-item__desc">...</p>
      
      <aside class="preview-item__meta">
        <time>10.10.10</time>
      </aside>
    </article>
  </div>

  <div class="blog-preview__item">...</div>
  
  <div class="blog-preview__item">...</div>
</aside>



Интересует нас отступ между новостями, которые задается .blog-preview__item { margin-bottom: 20px; }. Последний margin обнуляется, а нижний отступ делается за счет padding blog-preview. О чем говорилось во втором принципе.

Чаще чем другие псевдоклассы, надо использовать :last-child.

.item:not(:last-child) { 
  margin-bottom: 20px; 
}

// или //

.item {
  // другие стили //
  margin-bottom: 20px; 

  &:last-child {
    margin-bottom: 0;
  }
}

// или margin-top, основная идея здесь, не в направлении маргина, а в отсутствии лишнего //

.item + .item {
  margin-top: 20px;
}

// или //

.item {
  // другие стили //

  & + & {
    margin-top: 20px;
  }
}


Исключения


  • В первую очередь это добавление текстового контента через админку. Здесь отлично справляется подход к отступам заданный браузером. Но этот подход нельзя считать подходящим в обычной верстке как и несколько <br> в коде подряд.

  • Прижатие футера к низу окна браузера. Лучшим способом прижатия футера является способ на флексах. Где body задается минимальная высота, а не фиксированная(100%/vh), а футеру margin-top: auto;

    
    body {
      display: flex;
      flex-direction: column;
      min-height: 100vh;
    }
    
    .footer-page {
      margin-top: auto;
    }
    

  • Иногда вертикальные падинги лучше задавать дочерним блокам, нежели всей секции. Если в перспективе, на других страницах в том же месте, это относится ко второму принципу, задавать отступ для последнего возможного, вот иногда секция последний, но не возможный.
  • Отрицательные маргины, auto, padding для контейнера.
  • Подчеркивания слов. Когда нельзя воспользоваться бордером, то оптимальным способом будет использование псевдоэлемента :after.

    
    .title {
      // стили //
    
      &:after {
        content: '';
        display: block;
        width: 50%;
        height: 2px;
        margin-top: .5em;
        background-color: currentColor;
      }
    }
    


    Этот способ хорош тем, что не надо делать полоску абсолютной, и потом компенсировать отступами ее расстояние от текста.


Конечно есть частные случаи, нетривиальные задачи, и нюансы, при которых невозможно придерживаться этих принципов, но в остальном стоит стремиться к идеальным отступам, чтоб сделать верстку максимально чистой.
Поделиться публикацией
Похожие публикации
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама
Комментарии 44
  • 0
    Мне больше нравится, когда задан margin-top, а не margin-bottom
    И обнулять, как правило, ничего не приходится, т.к. отступ у блока сверху обычно больше, чем между его элементами. Его тоже прописываем как margin-top. Результирующий будет только один, который больше.
    • 0
      По своему опыту вёрстки в Ворде (извиняюсь, если оскорбил чьи-то чувства) могу сказать, что если отступы абзаца снизу, то вечные косяки и постоянно приходится допиливать документ до приличного вида напильником. Те самые «последние элементы группы». А если абзац рулит отступом перед собой, то сразу всё красиво. И потом меньше проблем при редактировании.
      • 0

        Сколько сложностей. Проще же элементам списка дать половинный margin, а контейнеру половинный padding.


        ul {
            padding: .5rem;
        }
        li {
            margin: .5rem;
        }

        У любой строки текста из-за line-height будет отступ сверху и снизу, который вы никак не уберёте (вариант с line-height=1 как правило не катит ибо не дружит с переносом текста). То есть вам в любом случае придётся учитывать, что у некоторый блоков будут симметричные отступы сверху и снизу. Поэтому лучше сразу всё и делать на симметричных отступах. Это и кода меньше займёт и лучше дружит с переносами блоков на новую строку.

        • 0
          По поводу отступов между однородными элементами. Самый правильный метод:
          .block__item + .block__item {
              margin-top: 1em;
          }

          Никаких last-child и прочего. Нужно придерживаться принципа, что стили должны как можно реже отменяться и переопределяться. То есть вместо «задать всем, а потом последнему отменить» нужно действовать по методу «задать сразу тем, кому нужно». Это и сокращение количества стилей (меньше рябит в глазах от каскада в девтулс), и семантически правильнее.
          • 0
            Я стараюсь не пользоваться "+", а то он может организовать разные нежданчики.
            Надо было в cms для лендинга завести поле для подзаголовка. Все шло нормально, прописала в шаблоне, что надо выводить поле с таким-то именем, и обернула в тег
            <h2 class="subtitle"></h2>
            Смотрю у подзаголовка нарисовались отступы, хотя все стили скинуты ресетом. В стилях класса «subtitle» я ни чего подобного не писала. Стерла «subtitle», а отступы есть. Поменяла на «h3» — все норм. Начала более внимательно просматривать какие стили применяются и нашла что-то вроде:
            h1 + h2 { margin: 10px;}
            • 0
              Так тут не плюс виноват, а навешивание стилей на теги. Надо пользоваться БЭМ-ом.
              • 0
                Что досталось, новые страницы уже, конечно, верстали по БЭМ.
            • 0
              Здесь критерием скорее служит отсутствие лишнего маргина, нежели направление.
            • 0
              Отступы идут в направлении потока дом дерева, блок сам себя не толкает.

              Единственный аргумент в пользу первого пункта и не выдерживает никакой критики.
              Блок себя не толкает, а вот элемент блока (как например элемент списка, где сам список является блоком) вполне себя толкает, в зависимости от своего контекста, а именно в зависимости от того что за элемент находится перед ним. В CSS нельзя задать зависимость от последующих элементов, но можно от предыдущих, в том и смысл задавать в таких случаях margin именно что левый и верхний.

              Кстати о смысле, какой смысл в том что элемент толкает что-то от себя вправо или вниз? Не особо большой, если вообще есть, не находите? Не чувствуется ли куда ли больший смысл в том что элемент может отталкиваться от чего-нибудь? Почувствуется, если задуматься ненадолго. В каком коде больше смысла, как думаете?

              1.
              .list {}
              .list__item {
                  // ... whatever else
              
                  margin-bottom: 10px;
              
                  &:last-child {
                      margin-bottom: 0;
                  }
              }
              


              2.
              .list {}
              .list__item {
                  // .. whatever else
              
                  & + & {
                      margin-top: 10px;
                  }
              }
              
              • 0
                Не чувствуется ли куда ли больший смысл в том что элемент может отталкиваться от чего-нибудь?

                А кроме того, элемент остается нейтральным и отталкивается только при определенных условиях.
                • 0
                  Семантически плюсовый селектор можно считать относящимся не к самим элементам (параграфу, например), а к их контексту, то есть фактически к родительскому уровню. Так что рассуждения, может ли блок толкать себя сам или соседа — не имеют большого смысла. Это не стиль конкретного блока, а что-то вроде правила построения коллектива.
                  • 0
                    Ну в принципе так и есть в большинстве ситуаций, отступ от предыдущего элемента определяется именно его нахождением в определенном контексте и может представлять из себя одно из правил взаимодействий элементов между собой в нем же.
                    Тем не менее даже в рамках набора правил взаимодействий элементов в блоке между собой, задание именно что отступа элемента от предыдущего имеет больше семантического смысла нежели задание отступа от элемента для последующих за ним (с обнулением, в случае если он последний или без него).

                    Кроме того, даже если не брать во внимание семантический смысл, чисто технически задание отступа в зависимости от предыдущего элемента дает значительно большие возможности и свободу стилизации без необходимости хаков/усложнений или изменений в верстке. Вот, например, ситуация:
                    .list__item {
                        & + & {
                            margin-top: 2px;
                        }
                        &--big + & {
                            margin-top: 4px;
                        }
                    
                        & + &--big {
                            margin-top: 10px;
                        }
                        &--big + &--big {
                            margin-top: 20px;
                        }   
                    }
                    

                    У элемента отступ от предыдущего 2 или 4 пикселя, в зависимости от того, что это за предыдущий элемент: list__item или list__item--big. И у элемента отступ от предыдущего 10 или 20 пикселей, в случае если этот элемент сам list__item или list__item--big, плюс аналогично все так же есть зависимость от вида предыдущего элемента.
                    Получились, так сказать, правила взаимодействий.
                    А теперь как реализовать данные отступы, если мы будем задавать нижний отступ и что-нибудь обнулять? Никак. Нижние отступы и обнуления это просто-напросто недостаточный набор инстументов для реализации в данном случае. При этом контекстно зависимые верхние отступы в данном случае более чем достаточный набор инстументов.

                    Однако ситуаций много разных, требования к проекту и верстке тоже везде разные, где-то нужна поддерживаемость, где-то нужно как можно проще или как можно непробиваемее, не везде возможно сочетать все плюсы и обойтись без минусов, где нужны именно что нижние отступы по о-очень замысловатым причинам, где-то комбинация их или даже супер-замысловатая и сложноподдерживаемая комбинация. Тем не менее, несмотря на все многообразие возможных ситуаций, если говорить о наиболее предпочтительном способе задания отступов для большинства случаев — это именно что отступы вверх и влево. Преподанный же автором «известный стандарт» задания отступов является несомненно известной вещью, вот только не стандартом, а крайне часто применяемым и крайне редко уместным или предпочтительным методом задания отступов, приводящим к более серьезным ошибкам верстки и более сложному процессу их исправления.
                    • 0
                      Ну кстати да — не существует ведь селектора, зеркального плюсовому.
                      • +2
                            & + & {
                                margin-top: 2px;
                            }
                            &--big + & {
                                margin-top: 4px;
                            }
                        
                            & + &--big {
                                margin-top: 10px;
                            }
                            &--big + &--big {
                                margin-top: 20px;
                            }   

                        Для тех, кто собирает имена классов по кусочкам (что в css, что в js) — есть отдельный котёл в аду.

                        • 0
                          Насчет имен согласен, а что насчет модификаторов?
                          • 0

                            А чем модификаторы хуже?

                            • 0
                              Модификаторы на то и модификаторы, что их названия не являются определяющими основное семантическое значение ни блока, ни элемента в блоке. Псевдоклассы :last-child, :first-child и тому подобные делают ровно ту же самую работу что и модификаторы в большинстве случаев, однако, я уверен, что вы не будет выступать против собирания конструкций с псевдоклассами вот такого рода:
                              .list__item {
                                  &:first-child {
                                      // .. whatever
                                  }
                              }
                              


                              Так что вопрос тут действительно в том «а чем модификаторы хуже?», только относится он к псевдоклассам — чем модификаторы хуже псевдоклассов? Чем они хуже, что за их собирание через &-- нужен отдельный котел в аду?
                              • 0

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

                                • 0
                                  На мой взгляд, это очень малый компромис, который стоит того — искать классы без учета модификаторов. Кроме того такие вещи все-таки оговариваются с новыми разработчиками на проекте, вдобавок к сотне других мелких вещей. А вот в незнакомом проекте лично я ищу полнотекстовым поиском вообще все что возможно reasonably найти: имя блока отдельно, имена элементов в блоке, отдельно модификаторы, все вместе, и даже части их, если это имеет смысл в конкретной ситуации. А все потому что неизвестно какой был контроль кода на незнакомом проекте, был ли он вообще, и были там какие-либо правила в принципе. Если же известно что там все четко и какие правила, то нет такой необходимости искать неизвестно что. Если контроль кода соблюдался четко, то собирание модификаторов не представляет никакой сложности для поиска использования класов. Однако в js и верстке я бы избегал даже собирания модификаторов настолько, насколько это возможно, но тоже не догматично.
                                  • 0
                                    Я пытаюсь писать sass как можно проще. Чтоб новый человек, и я старый мог легко вникнуть в проект. Конечно все оговаривается, но иногда кажется, что сасс используется ради сасса, а не для упрощения работы.
                                    Мне понравился доклад Вадима Макеева на эту тему.
                                    • 0
                                      В том, насколько новый человек (или тот же самый человек, что писал код, но в будущем) будет понимать код, принимают участие большое количество факторов, и простота стилей заключается не только в том применяются возможности препроцессора или нет.
                                      В данном случае вопрос был в использовании оператора & для сборки модификаторов. При использовании чистого css вместо scss не поменяется ни порядок задания правил, ни их логика, только синтаксис и единственный уровень вложенности. И это как раз та ситуация, где когнитивная нагрузка от дополнительного уровня абстракции в виде синтаксиса scss является достаточно малой, для того чтобы плюсы от его наличия перевешивали и снижали суммарный уровень нагрузки.

                                      Грубо говоря плюсов настолько больше по сравнению с минусами конкретно в ситуации с оператором & и модификаторами с псевдоклассами, что практически не бывает ситуаций где чистый css выиграл бы по сравнению с этим. По поддерживаемости, пониманию кода, написанию кода и т.д…

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

                                      Ну и так уж и быть, еще условие — отсутствие усложнений и маразмов в остальных местах проекта, будь то стили, скрипты или верстка, хоть сколько-нибудь имеющие отношение к этим самым классам. Если человек пишет так, что потом непонятно что происходит, то сборка модификаторов через &-- будет лишь еще одним его инструментом для усложнения. Ничего с этим не поделать. Без этого инструмента он будет использовать другой, и неизвестно хуже станет от другого инструмента или лучше. Поэтому я предлагаю этот момент все-таки на учитывать в рассуждении на эту тему. И тогда станет яснее видно явное превосходство одного подхода над другим.
                                      • 0

                                        Специально для вас, кусочек типичного кода, который получается у средней руки программиста при попытке следования БЭМ-у и экономии на нажатиях клавиш (ведь именно в этом основное преимущество &, да?)


                                        .panel-report
                                          min-width 700px
                                          height 100%
                                        
                                          &__head
                                            justify-content center
                                            align-content center
                                            min-height 40px
                                            margin 10ps
                                            padding 10px
                                            background $panel-head
                                        
                                          &__head-title
                                            color $panel-title
                                            text-align left
                                            max-width 50%
                                            padding 10px
                                            overflow hidden
                                        
                                            & > h1
                                              font-weight normal
                                              white-space nowrap
                                              padding 10px
                                              margin 0
                                              overflow hidden
                                              text-overflow ellipsis
                                              font-size: 20px
                                        
                                          &__wrapper
                                            width 100%
                                            display flex
                                        
                                            &--center
                                              .bench__blocks
                                                justify-content center
                                        
                                          &__blocks
                                            width 100%
                                            display flex
                                        
                                          &__block
                                            margin 10px
                                            border 1px solid $panel-border
                                            border-radius 4px
                                            background $panel-block-bg
                                            font-size 14px
                                            max-width 50%
                                            flex 1
                                            display flex
                                            flex-direction column
                                        
                                          &__title
                                            font-size 16px
                                            overflow hidden
                                            flex 0 0 60px
                                            display flex
                                            align-items center
                                        
                                            &--info
                                              cursor pointer
                                              user-select none
                                        
                                              &:hover
                                                background $hover-bg
                                        
                                                &:before
                                                  content '['
                                                  font-family monospace
                                                  margin-left -1ch
                                        
                                                &:after
                                                  content ']'
                                                  font-family monospace
                                                  margin-right -1ch
                                        
                                            &--text
                                                line-height 20px
                                                font-weight 600
                                                padding 10px
                                                color $panel-text
                                                text-align center
                                                overflow hidden
                                                text-overflow ellipsis
                                                flex 1 1 auto
                                        
                                          &__content
                                            padding 8px
                                            background $panel-value-bg
                                            margin 12px
                                            margin-top 0
                                            border 1px solid $panel-border
                                            border-radius 4px
                                            display flex
                                            flex-direction column
                                            flex 1 1 auto
                                        
                                          &__entity
                                            line-height 25px
                                            height 25px
                                            color $panel-text
                                        
                                            & > th
                                              font-weight normal
                                        
                                          &__entity-head
                                            vertical-align middle
                                        
                                          &__entity-row
                                            vertical-align middle
                                        
                                            & > em
                                              font-style normal
                                        
                                          &__power
                                            width 20px
                                            padding 0 6px
                                        
                                            &:after
                                              content '.'
                                        
                                          &__pos
                                            min-width 34px
                                            text-align right
                                            padding 0 6px
                                        
                                          &__name
                                            text-align right
                                            white-space nowrap
                                            text-overflow ellipsis
                                            overflow hidden
                                            font-size inherit
                                            max-width 180px
                                        
                                          &__val
                                            text-align right
                                            font-size inherit
                                            padding-left 8px
                                        
                                          &__br
                                            height 25px
                                            width 1px
                                            display block
                                            background $panel-border
                                        
                                          &__bar
                                            background-color $panel-bar-blue
                                            border none
                                            margin 0
                                            height 15px
                                            float left
                                        
                                            &.oil
                                              background-color $panel-bar-orange
                                        
                                          &__marker
                                            position relative
                                            margin auto
                                            cursor pointer
                                            flex 0 0 46px
                                        
                                          &__marker-indicator
                                            width: 34px;
                                            height: 34px;
                                            position: relative;
                                            background-size: 34px 34px

                                        Все имена изменены, все совпадения случайны.


                                        Сколько времени вам понадобится, чтобы найти место объявления стилей для следующего селектора?


                                        .panel-report__title--info:hover:before
                                        • 0
                                          Секунд 10. Потому что используя БЭМ, конечно же, нужно искать по имени блока, а не всему селектору целиком.

                                          И 2 встречных вопроса:
                                          1. Как часто приходится искать такие селекторы?
                                          2. Если писать всё полностью, то зачем вам препроцессор в принципе? Проще нативный CSS использовать.
                                          • 0
                                            Вот прежде чем использовать препроцессор, действительно нужно понять, зачем он вам нужен. Как и на нативном, так и на препроцессоре, можно говнокодить
                                            • 0
                                              Это общие слова, философия. Чуть конкретнее хотелось бы :)
                                            • 0

                                              10 секунд — довольно быстро для "дойти до нужной директории, найти нужный файл, найти нужное место в файле не запутавшись в контекстах".


                                              А были бы селекторы целиком — вы бы нашли искомое за пару секунд через ctrl+shift+f.


                                              1. Когда правишь баги вёрстки — очень часто. Когда новый код пишешь, конечно ничего искать не надо.


                                              2. Так многие (и я в том числе) уже отказались от препроцессоров в пользу css-next.
                                              • 0
                                                Угу, то есть в процессе правки стилей селекторы ищутся каждый раз «с нуля»? Поправил одно свойство и закрыл, а потом снова отправился искать?
                                                Нет, конечно, когда я работаю с каким-то блоком, я сразу ищу и открываю соответствующий ему файл. И дальше он у меня перед глазами, элементы и состояния ищутся легко.

                                                Применимость css-next для меня не вполне понятна, потому что с одной стороны в ней нем многих реально нужных вещей (которые есть в препроцессорах), но зато есть много очень передовых (но не так уж необходимых) рюшечек из будущих спецификаций и костыльный синтаксис вложенности.
                                            • 0
                                              Я, право же, ярый противник как sass-синтаксиса, так и собирания имен классов. А вот scss-синтаксис, и собирание модификаторов к имени класса я как раз и одобряю, при некоторых условиях конечно.

                                              Экономию нажатий я не приводил в качестве аргумента и не считаю экономию нажатий аргументом, имеющим сколько-нибудь существенный вес для его учета в абсолютном большинстве контекстов.

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

                                              А как вам вот такая переработка этого же кода? Видите ли вы в нем существенные минусы из-за собирания модификаторов через &--, и сложно ли в нем будет найти стили селектора .panel-report__title--info:hover:before?

                                              Код в scss со сборкой только модификаторов и псевдоклассов/псевдоэлементов
                                              .panel-report {
                                                  min-width: 700px;
                                                  height: 100%;
                                                  }
                                                  .panel-report__head {
                                                      justify-content: center;
                                                      align-content: center;
                                                      min-height: 40px;
                                                      margin: 10ps;
                                                      padding: 10px;
                                                      background: $panel-head;
                                                      }
                                                      .panel-report__head-title {
                                                          color: $panel-title;
                                                          text-align: left;
                                                          max-width: 50%;
                                                          padding: 10px;
                                                          overflow: hidden;
                                                  
                                                          & > h1 { // ! Спорное решение
                                                              font-weight: normal;
                                                              white-space: nowrap;
                                                              padding: 10px;
                                                              margin: 0;
                                                              overflow: hidden;
                                                              text-overflow: ellipsis;
                                                              font-size: 20px;
                                                              }
                                                          }
                                                      
                                                  .panel-report__wrapper {
                                                      width: 100%;
                                                      display: flex;
                                              
                                                      &--center {
                                                          .bench__blocks { // ! Здесь явно пошло что-то не так в БЭМ
                                                              justify-content: center;
                                                              }
                                                          }
                                                      }
                                                  
                                                  .panel-report__blocks {
                                                      width: 100%;
                                                      display: flex;
                                                      }
                                                      .panel-report__block {
                                                          margin: 10px;
                                                          border: 1px solid $panel-border;
                                                          border-radius: 4px;
                                                          background: $panel-block-bg;
                                                          font-size: 14px;
                                                          max-width: 50%;
                                                          flex: 1;
                                                          display: flex;
                                                          flex-direction: column;
                                                          }
                                                      
                                                  .panel-report__title {
                                                      font-size: 16px;
                                                      overflow: hidden;
                                                      flex: 0 0 60px;
                                                      display: flex;
                                                      align-items: center;
                                              
                                                      &:hover {
                                                          // Добавлено для иллюстрации взамного расположения
                                                          }
                                                      &:before {
                                                          // Аналогично
                                                          }
                                                      &:after {
                                                          // Аналогично
                                                          }
                                                      
                                                      &--info {
                                                          cursor: pointer;
                                                          user-select: none;
                                              
                                                          &:hover {
                                                              background: $hover-bg;
                                              
                                                              &:before {
                                                                  content: '[';
                                                                  font-family: monospace;
                                                                  margin-left: -1ch;
                                                                  }
                                                              &:after {
                                                                  content: ']';
                                                                  font-family: monospace;
                                                                  margin-right: -1ch;
                                                                  }
                                                              }
                                                          }
                                              
                                                      &--text {
                                                          line-height: 20px;
                                                          font-weight: 600;
                                                          padding: 10px;
                                                          color: $panel-text;
                                                          text-align: center;
                                                          overflow: hidden;
                                                          text-overflow: ellipsis;
                                                          flex: 1 1 auto;
                                                          }
                                                      }
                                                  
                                                  .panel-report__content {
                                                      padding: 8px;
                                                      background: $panel-value-bg;
                                                      margin: 12px;
                                                      margin-top: 0;
                                                      border: 1px solid $panel-border;
                                                      border-radius: 4px;
                                                      display: flex;
                                                      flex-direction: column;
                                                      flex: 1 1 auto;
                                                      }
                                                  
                                                  .panel-report__entity {
                                                      line-height: 25px;
                                                      height: 25px;
                                                      color: $panel-text;
                                              
                                                      & > th {
                                                          font-weight: normal;
                                                          }
                                                      }
                                                      .panel-report__entity-head {
                                                          vertical-align: middle;
                                                          }
                                                      .panel-report__entity-row {
                                                          vertical-align: middle;
                                              
                                                          & > em { // ! Нужен ли здесь > ?
                                                              font-style: normal;
                                                              }
                                                          }
                                                      
                                                  .panel-report__power {
                                                      width: 20px;
                                                      padding: 0 6px;
                                              
                                                      &:after {
                                                          content: '.';
                                                          }
                                                      }
                                                  .panel-report__pos {
                                                      min-width: 34px;
                                                      text-align: right;
                                                      padding: 0 6px;
                                                      }
                                                  .panel-report__name {
                                                      text-align: right;
                                                      white-space: nowrap;
                                                      text-overflow: ellipsis;
                                                      overflow: hidden;
                                                      font-size: inherit;
                                                      max-width: 180px;
                                                      }
                                                  .panel-report__val {
                                                      text-align: right;
                                                      font-size: inherit;
                                                      padding-left: 8px;
                                                      }
                                                  .panel-report__br {
                                                      height: 25px;
                                                      width: 1px;
                                                      display: block;
                                                      background: $panel-border;
                                                      }
                                                  .panel-report__bar {
                                                      background-color: $panel-bar-blue;
                                                      border: none;
                                                      margin: 0;
                                                      height: 15px;
                                                      float: left;
                                              
                                                      &.oil { // ! Что-то здесь не то
                                                          background-color: $panel-bar-orange
                                                          }
                                                      }
                                                  .panel-report__marker {
                                                      position: relative;
                                                      margin: auto;
                                                      cursor: pointer;
                                                      flex: 0 0 46px;
                                                      }
                                                      .panel-report__marker-indicator {
                                                          width: 34px;
                                                          height: 34px;
                                                          position: relative;
                                                          background-size: 34px 34px;
                                                          }
                                              


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

                                              И конкретно это место в коде можно написать несколькими вариантами в рамках все тех же правил, но уже это не касается модификаторов, а только сборки сочетаний :before и :hover. Вот, например, один из них:

                                              Другой вариант :hover:before
                                              &--info {
                                                  cursor: pointer;
                                                  user-select: none;
                                              
                                                  &:before,
                                                  &:after {
                                                      display: none;
                                              
                                                      font-family: monospace;
                                                      }
                                                  &:before {
                                                      content: '[';
                                              
                                                      margin-left: -1ch;
                                                      }
                                                  &:after {
                                                      content: ']';
                                              
                                                      margin-right: -1ch;
                                                      }
                                              
                                                  &:hover {
                                                      background: $hover-bg;
                                              
                                                      &:before,
                                                      &:after {
                                                          display: block;
                                                          }
                                                      }
                                                  }

                                      • +1
                                        Проблема поиска очень сильно преувеличена.
                                        На практике искать определения классов (имеется в виду по всему проекту) приходится на пару порядков реже, чем писать. Так что лучше вынести общее имя блока за скобки, чем городить его несколько десятков раз, создавая почву для опечаток и ошибок копипаста.
                                        Да и не нужно быть семи пядей во лбу, чтобы догадаться поискать по имени блока без модификатора — эта мысль приходит на автомате любому человеку, хоть сколько-нибудь понимающему БЭМ. Новый человек, не новый — не играет роли в данном случае. В самом крайнем случае — спросить!
                          • 0
                            Нет не на хожу никакого «смысла».
                            Список здесь представлен как простой пример, так как сложный в разы дольше разбирать.
                            Забудьте про список и про равные итемы.
                            Возьмем для примера это:

                            Отступ от заголовка к дате 20 пикселей.
                            Или для вас отступ от даты к заголовку 20 пикселей?
                            Если снести эту дату.
                            То отступ от заголовка станет уже 30 пикселей или для вас такой расклад приемлем? никогда не приходилось потом подгонять нужный отступ?

                            • 0
                              Не приходится подгонять если смотреть на верстку комплексно и со смыслом. Отступы не существуют сами по себе, это не самостоятельные сущности.

                              Судя только по картинке и не зная бизнес-логику и другие возможные комбинации элементов в этом блоке, могу предположить разбиение на блоки и отступы примерно вот так:
                              image

                              1. Заголовок — никаких отступов никуда
                              2. Дата+Статус, назовем этот блок Контент — никаких отступов никуда, но если Контент идет после Заголовка, то делаем отступ вверх
                              3. Чат — никаких отступов никуда, но если идет после Контента, то отступ до Контента тот что на скриншоте. Если возможна такая ситуация что Контента нет, а Чат есть, то мы легко можем дописать отступ вверх от Чата до Заголовка

                              А вот что происходит внутри Контента и какие там между собой отступы у элементов внутри уже дело самого блока Контент, но принцип остается тот же.

                              Понимаете теперь что смысл ищется исходя из, так сказать, бизнес-логики блоков, и что отступам желательно реализовывать именно что бизнес-логику, а не выравнивание по дизайну? (За выравнивание по дизайну отвечает размер отступа, а не факт его наличия/отсутствия и не условие его наличия/отсутствия)
                              • 0

                                Никогда не приходилось увольнять крикоруких дизайнеров, которые лепят отступы от балды?

                            • 0
                              Ваши принципы разобьются когда контент-менеджер будет заполнять страницу, и перед каким нибудь должен быть отступ больше чем перед параграфом. Он не будет делать специальные обертки, а повставляет простые
                              .
                              Конечно можно прописать p + h2{...}, p + p{...}, но тогда ваши стили будут ужасны для всех.
                              • 0
                                Для верстки «через админку», эти принципы конечно не подходят.
                              • 0
                                Больная тема для многих, кто занимается разработкой интерфейсов.
                                Причем это все можно стандартизировать.
                                Или может быть уже есть таковые стандарты?
                                Сколько раз сталкивался с проблемами padding и margin, особенно когда несколько человек делают front-end. Впору брошюру делать )
                                • 0
                                  По большему счету, стандартов, как таковых, не существует. Это больше похоже на культуру написания. Но люди любят делать отсебятину.
                                  • 0
                                    Это «головная боль» фронтенд разработчика. Подпишусь под комментарием, возможно, что-то кто-то расскажет. А еще лучше — есть ли набор неких «лучших практик» с учетом современных flex и grid по позиционированию елементов?
                                • –1
                                  Такое впечатление что автор пишет только одностраничники или сайты с постоянным контентом. «Сбрасывайте отступы у последних элементов», «задавайте margin-bottom»… Боже, да если б я такое творил меня б мой контентменеджер повесил за причинное место. Только margin-top, если ты прописываешь margin-bottom, то на это должна быть серьезная причина (Пример — хлебные крошки, или элемент между main и footer). Работаем сверху вниз, слева на право. А если контента по какой-то причине не будет? Ну не подключил человек модульный элемент из админки. Всё? Переписываем верстку, или вы выдумываете велосипеды под все случаи жизни с добавлением «классов затычек».
                                  • 0
                                    :last-child или :not(:last-child), конечно же, вы не используете?
                                    И, опять же, как решают указанные проблемы замена margin-bottom на margin-top?
                                  • 0
                                    Добавил небольшой перечень исключений
                                    • 0
                                      Тю, я думал здесь будет что-то эх какое, судя из заголовка и первого абзаца. Наверное, я что-то забыл? А оказалось, это набор ваших правил, которые у меня вызвали больше WTF, чем понимания зачем вы так делаете.
                                      • 0
                                        Не моих, мною озвученных. Здесь описана четкая модель.
                                        Чтоб понять зачем, наверное надо с эти поработать.
                                        • 0
                                          Вы считаете, я не работаю с вёрсткой? Преимуществ в вашей схеме я не вижу вообще

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