Левая выровненная последняя строка в центрированной сетке элементов

У меня есть набор одинаковых блоков, которые будут display:inline-block внутри div, который имеет text-align:center чтобы выровнять блоки.

|        _____   _____   _____   _____       |
|       |     | |     | |     | |     |      |
|       |  1  | |  2  | |  3  | |  4  |      |
|       |_____| |_____| |_____| |_____|      |
|        _____   _____   _____   _____       |
|       |     | |     | |     | |     |      |
|       |  5  | |  6  | |  7  | |  8  |      |
|       |_____| |_____| |_____| |_____|      |
|                                            |

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

|        _____   _____   _____        |
|       |     | |     | |     |       |
|       |  1  | |  2  | |  3  |       |
|       |_____| |_____| |_____|       |
|        _____   _____   _____        |
|       |     | |     | |     |       |
|       |  4  | |  5  | |  6  |       |
|       |_____| |_____| |_____|       |
|        _____   _____                |
|       |     | |     |               |
|       |  7  | |  8  |               |
|       |_____| |_____|               |
|                                     |

В настоящее время происходит следующее:

|        _____   _____   _____        |
|       |     | |     | |     |       |
|       |  1  | |  2  | |  3  |       |
|       |_____| |_____| |_____|       |
|        _____   _____   _____        |
|       |     | |     | |     |       |
|       |  4  | |  5  | |  6  |       |
|       |_____| |_____| |_____|       |
|            _____   _____            |
|           |     | |     |           |
|           |  7  | |  8  |           |
|           |_____| |_____|           |
|                                     |

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

Вот ручка, чтобы лучше продемонстрировать:

http://codepen.io/anon/pen/IDsxn

Это возможно? Я чувствую, что это точно. Я бы предпочел не использовать flexbox, поскольку это только ie10+, и я хотел бы ie9+. Мне бы очень понравилось чистое решение для CSS, но если вы скажете мне, что JS - единственный способ, мне бы хотелось увидеть это в действии.

Для справки - аналогичные вопросы, хотя ни один из них не был подробно объяснен:

Как выровнять левую последнюю строку/строку в нескольких линиях flexbox

CSS. Слева выровняйте последнюю строку изображений в центрированном div

Фиксация центрирования последней линии элементов в сетке контейнера для жидкости должна быть выровнена по левому краю, пока контейнер остается центрированным

Центрируйте несколько встроенных блоков с помощью CSS и выровняйте последнюю строку влево

Ответы

Ответ 1

Здесь очень простой JavaScript (и некоторые небольшие изменения в вашем CSS) для вас:

http://jsfiddle.net/ha68t/

Он отлично работает для меня.

CSS

.container {
  margin: 0 auto;
  max-width:960px;
  background-color: gold;
}

.block {
  background-color: #ddd;
  border:1px solid #999;
  display: block;
  float: left;
  height: 100px;
  margin: 4px 2px;
  width: 100px;
}

JavaScript:

$(document).ready(function(){
    setContainerWidth();
});

$(window).resize(function(){
   setContainerWidth();
});

function setContainerWidth()
{
    $('.container').css('width', 'auto'); //reset
    var windowWidth = $(document).width();
    var blockWidth = $('.block').outerWidth(true);
    var maxBoxPerRow = Math.floor(windowWidth / blockWidth);
    $('.container').width(maxBoxPerRow * blockWidth);
}

Требуется jQuery:)

Ответ 2

Решение с встроенным блоком отображения

Эта адаптивная сетка намного проще: меньше разметки и меньше CSS, поэтому ее проще будет внедрить на производственный сайт и адаптировать к вашим конкретным потребностям.

= → DEMO < = (изменить размер окна результатов, чтобы увидеть эффект)

html, body {
    margin:0;
    padding:0;
}
#container{
    font-size:0;
    margin:0 auto;
    width:1000px;
}
.block {
    font-size:20px;
    width: 150px;
    height: 150px;
    margin:25px;
    background: gold;
    display:inline-block;
}

@media screen and (max-width: 430px) {
    #container{
        width:200px;
    }
}

@media screen and (min-width: 431px) and (max-width: 630px) {
   #container{
        width:400px;
    }
}
@media screen and (min-width: 631px) and (max-width: 830px) {
   #container{
        width:600px;
    }
}
@media screen and (min-width: 831px) and (max-width: 1030px) {
   #container{
        width:800px;
    }
}
<div id="container">
    <div class="block">1</div>
    <div class="block">2</div>
    <div class="block">3</div>
    <div class="block">4</div>
    <div class="block">5</div>
    <div class="block">6</div>
    <div class="block">7</div>
    <div class="block">8</div>
    <div class="block">9</div>
    <div class="block">10</div>
    <div class="block">11</div>
    <div class="block">12</div>
    <div class="block">13</div>
</div>

Ответ 3

Для чего это стоит: сейчас 2017 и модуль компоновки сетки делает это из коробки

* {
    margin:0;
    padding:0;
}

.container {
  display: grid;
  grid-template-columns: repeat(auto-fill, 100px);
  grid-gap: 10px;
  justify-content: center;
  align-content: flex-start;
  margin: 0 auto;
  text-align: center;
  margin-top: 10px;
}
.block {
  background-color: #ddd;
  border: 1px solid #999;
  height: 100px;
  width: 100px;
}
<div class="container">
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
</div>

Ответ 4

С flexbox, некоторыми псевдоэлементами, дополнительным div, и после многих разочарований я смог добиться этого без медиа-запросов (так как мне нужно было поставить свою сетку внутри множества разных элементов, запросы на медиа не будут действительно работают для меня).

Одно предостережение: водосточные желоба между предметами являются текучими.

Демо: http://codepen.io/anon/pen/OXvxEW

CSS

.wrapper {
    display: flex;
    flex-wrap: wrap;
    border: 2px solid #ffc0cb;
    max-width: 1100px;
    margin: 0.5rem auto;
    justify-content: center;
}

.wrapper:after {
    content: ' ';
    flex: 1;
    height: 100%;
    border: 1px solid #00f;
    margin: 0.5rem;
}

.child {
    flex: 1;
    border: 2px solid #ffa500;
    min-width: 300px;
    margin: 0.5rem;
    text-align: center;
}

.child-contents {
    width: 300px;
    border: 2px solid #008000;
    height: 100px;
    margin: 0 auto;
}

HTML:

<div class='wrapper'>
    <div class='child'>
        <div class='child-contents'></div>
    </div>
    <div class='child'>
        <div class='child-contents'></div>
    </div>
    <div class='child'>
        <div class='child-contents'></div>
    </div>

    ...etc., more .child's...

</div>

Конечным результатом является что-то вроде этого, где зеленые прямоугольники являются div. Розовые/оранжевые границы предназначены только для справки, чтобы вы могли видеть, что происходит. Если вы удалите розовые/оранжевые границы, вы должны получить сетку, которую вы ищете (хотя, опять же, обратите внимание, что водосточный желоб является жидким).

введите описание изображения здесь

Ответ 5

Используйте flexbox:

.container {
  display: -webkit-flex;
   display: flex;
   -webkit-flex-direction: row; 
   flex-direction: row;
   -webkit-justify-content: flex-start;
   justify-content: flex-start;
   flex-wrap:wrap;
}

.block {
  background-color: #ddd;
  border:1px solid #999;
  display: inline-block;
  height: 100px;
  margin: 4px 2px;
  width: 100px;
}

Готово.

Ответ 6

На сегодняшний день единственным чистым решением для этого является

Модуль компоновки CSS-сетки (Демо-версия Codepen)

В основном соответствующий необходимый код сводится к следующему:

ul {
  display: grid; /* (1) */
  grid-template-columns: repeat(auto-fill, 120px); /* (2) */
  grid-gap: 1rem; /* (3) */
  justify-content: center; /* (4) */
  align-content: flex-start; /* (5) */
}

1) Сделайте контейнерный контейнер контейнером сетки

2) Установите сетку с "авто" количеством столбцов шириной 120 пикселей. (Значение автозаполнения используется для гибких макетов).

3) Установите зазоры/водосточные трубы для строк и столбцов сетки.

4) и 5) - Подобно flexbox.

body {
  margin: 0;
}
ul {
  display: grid;
  grid-template-columns: repeat(auto-fill, 120px);
  grid-gap: 1rem;
  justify-content: center;
  align-content: flex-start;
  
  /* boring properties: */
  list-style: none;
  width: 90vw;
  height: 90vh;
  margin: 2vh auto;
  border: 5px solid green;
  padding: 0;
  overflow: auto;
}
li {
  background: tomato;
  height: 120px;
}
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
  <li>6</li>
  <li>7</li>
  <li>8</li>
  <li>9</li>
  <li>10</li>
</ul>

Ответ 7

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

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

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

Ответ 8

Попробуйте это с помощью простого css:

CSS

.row {выравнивания текста: центр; размер шрифта: 0;} .block {выравнивания текста: центр; дисплей: встроенный блок; ширина: 150px; высота: 15px; поле: 5px; border: 1px solid #dddddd; font-size: 13px;}

HTML:

<div class="row">
  <div class="block"></div> 
</div>

.row{text-align:center;font-size:0;}
    .block{text-align:center;display:inline-block;width:150px;height:150px;margin:5px; border:1px solid #dddddd;font-size:13px;line-height:150px;}
<div class="row">
      <div class="block">1</div> 
      <div class="block">2</div> 
      <div class="block">3</div> 
      <div class="block">4</div> 
      <div class="block">5</div> 
      <div class="block">6</div> 
      <div class="block">7</div> 
      <div class="block">8</div> 
    </div>