Выровняйте 3 неравных блока слева, по центру и справа

Я пытаюсь выровнять верхнее меню, состоящее из 3 блоков контента.

Чего я пытаюсь добиться, так это:

  • блок 1: выровнен по левому краю
  • блок 2: по центру по горизонтали
  • блок 3: выровнен по правому краю

Если бы все 3 блока были одинакового размера, я мог бы использовать flexbox (как во фрагменте), но это не так, поэтому он не производит требуемый результат.

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

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

.container {
  margin: 20px 0;
}

.row {
  background-color: lime;
  display: flex;
  justify-content: space-between;
}

.item {
  background-color: blue;
  color: #fff;
  padding: 16px;
}
<div class = "container">
  <div class = "row">
    <div class = "item">left, slightly longer</div>
    <div class = "item">center, this item is much longer</div>
    <div class = "item">right</div>
  </div>
</div>

Я просмотрел «дубликаты» ответов. Это не тот сценарий. Все решения flex и auto margin в посте основаны на блоках «одного размера», что является здесь ключевым отличием. Сетка недостаточно поддерживается.

John Ohara 28.03.2019 09:52

можете ли вы дать "flex-grow: 1;" для класса ".item" и проверьте

Rajesh 28.03.2019 10:02

У меня был тот же вопрос, и я наткнулся на отличный Почему в CSS Flexbox нет свойств «justify-items» и «justify-self»?, который стоит прочитать и содержит ответы, дающие несколько решений, отличных от текущий принятый ответ ниже.

handle 07.03.2020 11:52
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
CSS: FlexBox
CSS: FlexBox
Ранее разработчики использовали макеты с помощью Position и Float. После появления flexbox сценарий полностью изменился.
8
3
1 494
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

можете ли вы дать flex-grow:1 для класса элемента и проверить

.item {
background-color: blue;
color: #fff;
padding: 16px;
flex-grow:1;
}

Надеюсь, это то, что вы ищете

Ответ принят как подходящий

Вы можете рассмотреть flex-grow:1;flex-basis:0% для левого и правого элементов, а затем использовать text-align для выравнивания содержимого внутри. Я добавил дополнительную оболочку, чтобы фон оставался только вокруг текста.

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

.container {
  margin: 20px 0;
  padding-top:10px;
  background:linear-gradient(#000,#000) center/5px 100% no-repeat; /*the center*/
}

.row {
  background-color: lime;
  display: flex;
  color: #fff;
}

.item:not(:nth-child(2)) {
  flex-basis: 0%;
  flex-grow: 1;
}

.item:last-child {
  text-align: right;
}

.item span{
  background-color: blue;
  display:inline-block;
  padding: 16px;
  border: 2px solid red;
  box-sizing:border-box;
}
<div class = "container">
  <div class = "row">
    <div class = "item"><span>left, slightly longer</span></div>
    <div class = "item"><span>center, this item is much longer</span></div>
    <div class = "item"><span>right</span></div>
  </div>
</div>

Вы также можете сделать то же самое, удерживая элемент рядом. Просто настройте выравнивание текста:

.container {
  margin: 20px 0;
  padding-top: 10px;
  background: linear-gradient(#000, #000) center/5px 100% no-repeat; /*the center*/
}

.row {
  background-color: lime;
  display: flex;
  color: #fff;
}

.item:not(:nth-child(2)) {
  flex-basis: 0%;
  flex-grow: 1;
}

.item:first-child {
  text-align: right;
}

.item span {
  background-color: blue;
  display: inline-block;
  padding: 16px;
  border: 2px solid red;
  box-sizing: border-box;
}
<div class = "container">
  <div class = "row">
    <div class = "item"><span>left, slightly longer</span></div>
    <div class = "item"><span>center, this item is much longer</span></div>
    <div class = "item"><span>right</span></div>
  </div>
</div>

Можешь объяснить .item:not(:nth-child(2)) ?

CodyBugstein 28.03.2019 15:34

@CodyBugstein это означает не выбирать второго ребенка. Поэтому я применяю CSS только к первому и последнему

Temani Afif 28.03.2019 15:34

Ах, ладно, я думал, вы пытаетесь обобщить решение ситуаций с более чем 3 элементами.

CodyBugstein 28.03.2019 15:37

Альтернатива с использованием таблицы отображения (древняя поддерживаемая сетка).

Цитата из https://www.w3schools.com/cssref/pr_tab_table-layout.asp

If no widths are present on the first row, the column widths are divided equally across the table, regardless of content inside the cells

.container {
   display: table;
   table-layout: fixed
 } // would divide cells equally along table's 100% width. 
.row {
   display: table-row
 }
.item {
   display: table-cell
 }

Я задал очень похожий вопрос, и переполнение стека направило меня сюда. Ответ от @Paolamoralesval вдохновил меня на то, чтобы понять, что требуемый эффект может быть достигнут с помощью сетки CSS. Теперь, когда поддержка сетки стала универсальной, я надеюсь, что она удовлетворит все потребности. Я считаю, что это решение полностью реагирует на размер окна, а также на высоту и ширину элементов заголовка, как вы должны увидеть, если вы измените размер окна, в котором вы просматриваете фрагмент.

.header {
  grid-row: 1;
  grid-column: 1;
  display: grid;
  grid-template-rows: min-content;
  grid-template-columns: 1fr 1fr 1fr;
}
.header-left {
  justify-self: start;
  align-self: center;
  text-align: left;
  background-color: red;
}
.header-center {
  justify-self: center;
  align-self: center;
  text-align: center;
  background-color: green;
}
.header-right {
  justify-self: end;
  align-self: center;
  text-align: right;
  background-color: blue;
}
.shrink-kitty {
    width: 200px;
}
<html>
  <body>
    <div class = "page">
      <div class = "header">
          <div class = "header-left">
            <img class = "shrink-kitty" src = "https://upload.wikimedia.org/wikipedia/commons/thumb/b/bb/Kittyply_edit1.jpg/1280px-Kittyply_edit1.jpg"/><br/>
            By David Corby<br/>
            Edited by: <a href = "//commons.wikimedia.org/wiki/User:Arad" title = "User:Arad">Arad</a><br/><a href = "//commons.wikimedia.org/wiki/File:Kittyplya03042006.JPG" title = "File:Kittyplya03042006.JPG">Image:Kittyplya03042006.JPG<a><br/><a href = "https://creativecommons.org/licenses/by/2.5" title = "Creative Commons Attribution 2.5">CC BY 2.5</a>, <a href = "https://commons.wikimedia.org/w/index.php?curid=1839754">Link</a>
          </div>
          <div class = "header-center">In the middle</div>
          <div class = "header-right">
            Much much much much more on the right hand side</br>
            Indeed two lines
          </div>
      </div>
      <div class = "body">Body of the page</div>
      <div class = "footer">At the bottom</div>
    </div>
  </body>
</html>

Другие вопросы по теме