Как получить центрирование по центру и выравнивание по левому краю в одно и то же время

У меня есть контейнер с плитами (или div), и я хочу, чтобы контейнер был центрирован, а фрагменты оставлены в контейнере.

поэтому, если окно мало:

..[s][s][s]..
..[s][s].....

Если окно немного расширилось:

...[s][s][s]...
...[s][s]......

далее:

.[s][s][s][s].
.[s]..........

Я пробовал:

#container's-parent: { display: block; text-align: center; }
#parent: { display: inline-block; text-align: left; }
.tiles: { display: inline-block }

но это не работает.

Я хочу, чтобы это работало в Chrome по крайней мере, но мне также необходимо в конечном итоге поддерживать последние FF, Safari и IE 10 +

Ответы

Ответ 1

FWIW: теперь 2017 и модуль компоновки сетки делает это из коробки (демо-версия codepen). Если вам подходит поддержка браузера, используйте сетку. Если нет, то читайте дальше....


Как упоминалось в ответе @Skadi2k3, лучшее, что вы можете сделать с CSS, - это серия медиа-запросов.

При этом, если вы используете препроцессор, такой как LESS - это не такая сложная или подверженная ошибкам задача. (хотя, да, CSS все равно будет длинным и уродливым)

FIDDLE или CODEPEN (поддержка LESS)

Здесь, как использовать LESS для настройки медиа-запросов:

Настройте итерационный микс следующим образом: (Вы можете вставить этот код в http://less2css.org)

@item-width:100px;
@item-height:100px;
@margin: 5px;
@min-cols:2;
@max-cols:12; //set an upper limit of how may columns you want to write the media queries for


.loopingClass (@index-width) when (@index-width <= @item-width * @max-cols) {
    @media (min-width:@index-width) {
        #content{
            width: @index-width;
        }
    }

    .loopingClass(@index-width + @item-width);
}

.loopingClass (@item-width * @min-cols);

Вышеупомянутый mixin выплюнет серию медиа-запросов в форме:

@media (min-width: 200px) {
  #content {
    width: 200px;
  }
}
@media (min-width: 300px) {
  #content {
    width: 300px;
  }
}
@media (min-width: 400px) {
  #content {
    width: 400px;
  }
}
...
@media (min-width: 1200px) {
  #content {
    width: 1200px;
  }
}

Итак, с простой разметкой вроде:

<ul id="content">
    <li class="box"></li>
    <li class="box"></li>
    ...
    <li class="box"></li>
</ul>

С оставшимся CSS (LESS):

 #content {
    margin:0 auto;
    overflow: auto;
    min-width: @min-cols * @item-width;
    max-width: @max-cols * @item-width;
    display: block;
    list-style:none;
    background: aqua;
}
.box {
    float: left;
    height: @item-height - 2 *@margin;
    width: @item-width - 2*@margin;
    margin:@margin;
    background-color:blue;
}

... вы получите желаемый результат.

... и очень легко настроить макет:

Все, что мне нужно сделать, это изменить переменные, которые я использовал в LESS mixin в соответствии с моими потребностями, - я получаю точный макет, который мне нужен.

Итак, скажем, у меня есть элементы 300px X 100px с минимум двумя столбцами и максимум 6 столбцами и полем 15px - я просто изменяю такие переменные:

@item-width:300px;
@item-height:100px;
@margin: 15px;
@min-cols:2;
@max-cols:6;

... и voila, я получаю это CODEPEN

Ответ 2

Как насчет этого?

http://jsfiddle.net/cHTVd/1/

enter image description here

Вы также должны установить display: inline-block для контейнера:

body { text-align: center; }

#container { 
    width: 250px; 
    border: solid green 3px; 
    display: inline-block; 
    text-align: left; 
}

.tile { width: 100px; 
    border: solid red 3px;
    display: inline-block;
    margin: 8px;
}

EDIT: Предоставление относительной ширины контейнера легко - http://jsfiddle.net/cHTVd/3/

Я боюсь, что с "JS" должно быть сделано "обратное оправдание". CSS text-align имеет только четыре значения: left | право | центр | обосновывать. Это тривиально, чтобы изменить его, чтобы оправдать - http://jsfiddle.net/cHTVd/4/. Для "обратного обоснования" вам, вероятно, понадобится работа с javascript, подобная этому: http://jsfiddle.net/yjcr7/2/.

Ответ 3

Если вы не хотите использовать Javascript, вы можете использовать медиа-запрос (многие из них):

#parent{ width: 100px; margin: 0 auto;padding:0;}
.tile{width: 80px; float:left;padding:10px;outline:2px dashed red;}
@media screen and (max-width:200px)
@media screen and (min-width:201px) and (max-width:300px){
    #parent{ width: 200px;}
}
@media screen and (min-width:301px) and (max-width:400px){
    #parent{ width: 300px;}
}
@media screen and (min-width:401px){
    #parent{ width: 400px;}
}

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

Ответ 4

Я решил это на своих собственных проектах быстро и грязно, просто добавив несколько пустых "плиток" до конца, которые имеют ту же ширину, что и обычные плитки контента, но с незначительной высотой. Эти пустые плитки служат для "толчки" фрагментов контента на последней строке слева, где они принадлежат. ( "Реальная" последняя строка часто состоит из ничего, кроме пустых фрагментов, которые невидимы для пользователя.) Так, например, если на странице есть несколько фрагментов, и я ожидаю, что ширина браузера будет в состоянии разместить от 1 до 4 (например) плиток шириной, я добавлю до 3 дополнительных пустых плиток (обозначенных "е" ) до конца:

..[s][s][s]..
..[s][s][e]..
...[e][e]....  // this row isn't visible because [e] has no content

Если окно немного расширилось:

...[s][s][s]...
...[s][s][e]...
....[e][e].....

далее:

.[s][s][s][s].
.[s][e][e][e].

или более узкий:

.[s][s].
.[s][s].
.[s][e].
.[e][e].

или действительно узкий

..[s]..
..[s]..
..[s]..
..[s]..
..[s]..
..[e]..
..[e]..
..[e]..

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

Разумное решение для хакеров, но оно действительно работает, надежно работает в разных браузерах и не требует насыщения кода.

Ответ 5

Попробуйте следующее:

.tiles: { 
  display: inline-block;
  margin: 0 auto;
  max-width: 90%;
}

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

Ответ 6

Это довольно легко с flexbox.

.container { дисплей: flex; flex-wrap: wrap; }

Вы можете настроить, как плитки подходят, например, дать им исходную точку (flex-basis) или размер плитки может расти или уменьшаться

.tile { flex-grow: 0; flex-shrink: 0; flex-basis: 3em;

Проверьте код: http://codepen.io/anon/pen/uexbf

Ответ 7

Похоже, есть решение (хотя оно описано на русском языке, и я не нашел перевода).
Демо можно увидеть здесь.

Ответ 8

Не знаю, как это сделать с помощью CSS, если это возможно. Но с jQuery он довольно прост:

$('button').click(function(){

  $('nav ul').each(function(){
    
    $parent = $(this).parent();
    
    $parent.width( $(this).width() );
    
  });
});
nav {
  display: inline-block;
  text-align: left; /* doesn't do anything, unlike some might guess */
}
ul {
  display: inline;
}

/* needed style */
ul {
  padding: 0;
}
body {
  width: 420px;
}

/* just style */
body {
  background: #ddd;
  margin: 1em auto;
}
button {
  display: block;
}
nav {
  background: #bbb;
  margin: 1rem auto;
  padding: 0.5rem;
}
li {
  display: inline-block;
  width: 40px;
  height: 20px;
  border: solid thin #777;
  margin: 4px;
  background: #999;
  text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<button>fix</button>

<nav>
  <ul>
    <li>3</li>
    <li>.</li>
    <li>1</li>
    <li>4</li>
  </ul>
</nav>

<nav>
  <ul>
    <li>3</li>
    <li>.</li>
    <li>1</li>
    <li>4</li>
    <li>1</li>
    <li>5</li>
    <li>9</li>
    <li>2</li>
    <li>6</li>
    <li>5</li>
    <li>3</li>
    <li>5</li>
  </ul>
</nav>

Ответ 9

Отвечайте так же, как Danield, но в SCSS:

*
{
    margin:0;padding:0;
}

$item-width:200px;
$item-height:100px;
$margin: 15px;
$min-cols:2;
$max-cols:6; //set an upper limit of how may columns you want
             //to write the media queries forss to css

@for $i from $min-cols to $max-cols + 1 {
  $index-width: $i*$item-width;
  @media (min-width:$index-width) {
    #content {
      width: $index-width;
    }
  }
}


#content {
    margin:0 auto;
    overflow: auto;
    min-width: $min-cols * $item-width;
    max-width: $max-cols * $item-width;
    display: block;
    list-style:none;
    background: aqua;
}
.box {
    float: left;
    height: $item-height - 2 *$margin;
    width: $item-width - 2*$margin;
    margin:$margin;
    background-color:blue;
}

Он генерирует тот же CSS, что и его решение.

Пример рабочего кодекса здесь.