Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get tiles centered and left-justified at the same time

Tags:

html

css

I have a container of tiles (or divs) and I want the container to be centered, while the tiles are left justified in the container.

so if the window is small:

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

If the window is widened a little:

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

further:

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

I've tried:

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

but that doesn't appear to work.

I want this to work in Chrome at least, but I also need to eventually support latest FF, Safari, and IE 10+

like image 241
Sophie McCarrell Avatar asked Jan 15 '14 19:01

Sophie McCarrell


People also ask

How do I align an item to the center of the screen?

You can do this by setting the display property to "flex." Then define the align-items and justify-content property to “center.” This will tell the browser to center the flex item (the div within the div) vertically and horizontally.

How to align the text in center?

Select the text that you want to center. in the Page Setup group, and then click the Layout tab. In the Vertical alignment box, click Center. In the Apply to box, click Selected text, and then click OK.

How do I center text vertically in CSS?

To center both vertically and horizontally, use padding and text-align: center : I am vertically and horizontally centered.

How do I put text on the right side in HTML?

We can change the alignment of the text using the text-align property. We can align the text in the center, Left, Right. The text alignment can be done with CSS(Cascading Style Sheets) and HTML Attribute tag. Note: The left alignment of the text is default.


3 Answers

FWIW: It's now 2017 and the grid layout module does this out of the box (codepen demo). If the browser support suits you - then use grid. If not, then read on....


As mentioned in @Skadi2k3's answer, the best you can do with CSS is with a series of media queries.

That being said, if you are using a preprocessor such as LESS - this isn't such a difficult or error-prone task. (although, yes, the CSS will still be long and ugly)

FIDDLE or CODEPEN (Supports LESS)

Here's how to take advantage of LESS to set up the media queries:

Set up an iteration mixin like this: (You can paste this code into 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);

The above mixin will spit out a series of media queries in the form:

@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;
  }
}

So with a simple markup like:

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

With remaining 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;
}

... you get the desired result.

...and it's super easy to customize the layout:

All I need to do is change the variables that I used in the LESS mixin according to my needs - I get the exact layout that I'm after.

So let's say I have items 300px X 100px with a minimum of 2 columns and max 6 columns and a margin of 15px - I just modify the variables like so:

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

...and voila, I get this CODEPEN

like image 133
Danield Avatar answered Oct 16 '22 11:10

Danield


What about this?

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

enter image description here

You have to set display: inline-block for the container too:

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: Giving container relative width is easy - http://jsfiddle.net/cHTVd/3/

I am afraid that "reverse justify" would have to be done with JS. CSS text-align has only four values: left | right | center | justify. It's trivial to change it to justify - http://jsfiddle.net/cHTVd/4/. For the "reverse justify" you would probably need some javascript work similar to this: http://jsfiddle.net/yjcr7/2/.

like image 34
Tomas Avatar answered Oct 16 '22 12:10

Tomas


Unless you want to use Javascript you could use the media query (lots of them):

#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;}
}

The problem is that you need to know how many of the tiles fit into the container to set a tight fitting width to the container, but that is a bottom up information and not how cascading works. If you want a more elegant solution you need to use JS on resize events, calculate how many boxes fit into one line and set the width of the container.

like image 24
Skadi2k3 Avatar answered Oct 16 '22 11:10

Skadi2k3