简体   繁体   中英

CSS - Grid row centering

I got a grid, made out of inline-block elements so they can overflow to other rows.

The problem is that, if the row is not complete, the items in that row are also centered and not aligned to the left side, like if they'd just overflow.

The problem can be seen in this Fiddle .

Is there any way to do this in the pure CSS ? So that the container is centered, but the elements inside it remain to be on the left side ?

I already tried to use margin: 0 auto; to center just the container, but the container would have to have fixed width, but in this situation the container expands as far as it can (fills the outer container).

Edit: The only way I can think of is getting the width of the container with Javascript and then dividing the width by the width of the elements (as they have the same width), apply the width to the container and go with the margin: 0 auto; method.

This is not doable in a general case ( see this post ) because CSS can't determine when an element wraps and therefore recalculate the empty space required.

Similar to the solution in that post, you can use media queries to achieve this result. I have written a version more specific to your case:

 .grid { margin: 0 auto; width: 990px; font-size: 0; } .item { display: inline-block; margin: 5px; width: 100px; height: 100px; background: red; } @media screen and (max-width: 230px) { .grid { width: 110px; } } @media screen and (min-width: 231px) and (max-width: 340px) { .grid { width: 220px; } } @media screen and (min-width: 341px) and (max-width: 450px) { .grid { width: 330px; } } @media screen and (min-width: 451px) and (max-width: 560px) { .grid { width: 440px; } } @media screen and (min-width: 561px) and (max-width: 670px) { .grid { width: 550px; } } @media screen and (min-width: 671px) and (max-width: 780px) { .grid { width: 660px; } } @media screen and (min-width: 781px) and (max-width: 890px) { .grid { width: 770px; } } @media screen and (min-width: 891px) and (max-width: 1000px) { .grid { width: 880px; } } @media screen and (min-width: 1001px) and (max-width: 1110px) { .grid { width: 990px; } } 
 <div class="grid"> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> </div> 

Writing this many media queries, however, is not advised. I actually generated them using Sass (see my CodePen ):

$width: 100px;
$margin: 5px;
$extra-padding: 10px;
$column-width: $width + 2 * $margin;
$num-blocks: 9;

@function screen-size($n) {
  @return $n * $column-width + $extra-padding;
}

.grid {
  margin: 0 auto;
  width: $num-blocks * $column-width;
  font-size: 0;
}

.item {
  display: inline-block;
  margin: $margin;
  width: $width;
  height: 100px;
  background: red;
}

@media screen and (max-width: screen-size(2)) {
  .grid {
    width: $column-width;
  }
}

@for $i from 2 through $num-blocks {
  @media screen and (min-width: screen-size($i) + 1px) and (max-width: screen-size($i + 1)) {
    .grid {
      width: $i * $column-width;
    }
  }
}

The above solution has its limitations, it can only work with fix number of blocks. If that's a concern, you will have to use a JavaScript library such as Desandro Masonry or just roll your own.

It seems like it's not possible to do it with CSS only approach (unless using Flexbox).

That means I'm going to use the "set width with Javascript and use margin: 0 auto" method.

The best would be to use the CSS only method proposed by @Nelson Yeung, but I'm going to use it on multiple pages, where the container width would not be the same.

Also interesting thing is that Zeplin, platform for front-end developers <> designers, is also using the method I'm going to use.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM