15

I'm trying to get 5 divs aligned inside a div, like this:

enter image description here

Is there any way to do this without using margin-left?

I mean.. In case I want to eliminate one of this middle divs and they still be aligned? For example.. If I remove div4, the others will be centered automatically. Like this:

enter image description here

I found a solution like this:

#parent {
  width: 615px;
  border: solid 1px #aaa;
  text-align: center;
  font-size: 20px;
  letter-spacing: 35px;
  white-space: nowrap;
  line-height: 12px;
  overflow: hidden;
}
.child {
  width: 100px;
  weight: 100px;
  border: solid 1px #ccc;
  display: inline-block;
  vertical-align: middle;
}

But the problem is: The first div and the last one must be like float left and float right... And this solution centers every thing resulting something like this:

enter image description here

shilovk
  • 11,718
  • 17
  • 75
  • 74
Marcelo Barganha
  • 369
  • 5
  • 14
  • You should look at twitterbootstrap.com. I think this will save you a lot of time. http://getbootstrap.com/css/#grid-responsive-resets – Sari Rahal Jun 08 '15 at 20:37
  • Bootstrap is not an option in this case.. – Marcelo Barganha Jun 08 '15 at 20:39
  • are you using scss? does the width of the divs have to be set in pixels? do you require a responsive solution? – Toni Leigh Jun 08 '15 at 20:41
  • 1
    It's a local system for PC. So, width set in pixels. No need to be responsive. – Marcelo Barganha Jun 08 '15 at 20:42
  • what about the overall container width, is that set in pixels? – Toni Leigh Jun 08 '15 at 20:43
  • might be duplicate of [http://stackoverflow.com/questions/6865194/fluid-width-with-equally-spaced-divs](http://stackoverflow.com/questions/6865194/fluid-width-with-equally-spaced-divs) – Amit.rk3 Jun 08 '15 at 20:56
  • I posted an answer with all the correct prefixes to support as many browsers as possible. Please check it out. The existing answer is not responsible web design. – M H Jun 09 '15 at 06:48

5 Answers5

10

The flexbox might be the answer you're looking for.

#container {
  display: flex;
  justify-content: space-between;
  border: 1px solid black;
  background: #ccc;
}
#container>div {
  width: 100px;
  border: 1px solid black;
  background: #fff;
  height: 100px;
}
<div id="container">
  <div>box 1</div>
  <div>box 2</div>
  <div>box 3</div>
  <div>box 4</div>
  <div>box 5</div>
</div>

If you want to maximise browser compatibility, be sure to also add the correct vendor prefixes:

#container {
  display: -moz-flex;
  display: -ms-flex;
  display: -webkit-flex;
  display: flex;
  /* … */
}
Blackhole
  • 20,129
  • 7
  • 70
  • 68
Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
  • 2
    Although the flexible box model is definitely the solution to these kind of problems, mentioning a solution like this should at all times also include a note about browser compatibility: http://caniuse.com/#feat=flexbox – David Mulder Jun 08 '15 at 23:22
  • Totally agree with @DavidMulder This has very bad browser support. See this article to use all the correct prefixes: https://css-tricks.com/using-flexbox/ and here at caniuse: http://caniuse.com/#feat=flexbox you can see that any android older than 4.1 will break and any iOS before 7 will break. – M H Jun 09 '15 at 06:28
  • 1
    I posted an answer below with all the prefixes to support as many browsers as possible. – M H Jun 09 '15 at 06:45
  • 1
    Safari is the only current browser that doesn't support flexbox without prefixes. Personally I don't think it's worth duplicating my code with prefixes (either manually or automatically, in both cases it's a pain to do and is a colossal waste of bandwidth) just to accommodate users who don't take the minute or two it takes to click the "Update" button on their browsers. That is, however, purely my opinion on the matter: if people are too lazy to upgrade, then I'm too lazy to code for them. – Niet the Dark Absol Jun 09 '15 at 16:26
  • 1
    @NiettheDarkAbsol - unfortunately some people can't upgrade, they might be stuck on old operating systems or simply not technically astute enough to do so, coding for everyone makes us good coders, but, there's a neat plugin for Grunt that uses caniuse.com and automatically adds the correct prefixes for a developer defined browser set, it's all done at compile stage and is a very useful tool: https://github.com/postcss/autoprefixer – Toni Leigh Jun 15 '15 at 19:15
6

maybe so

text-align: justify - this feature works with text, as well as our line-block (display: inline-block) points, in fact, and are inseparable words in a row, this behavior is quite natural.

Incidentally, it is worth considering that the text-align: justify inherited property, so text-align: left at the next descendants - a necessary measure. In this way, we would return as the alignment of the content of our blocks in the former state.

This algorithm does not apply to the last line, and works with all lines except her.Therefore, using :after I added to the end of another element, pacifier, and stretched it to 100% of the width, thus forcing him to stretch out on the very last line in the list.

*{
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}

div {    
    text-align: justify; 
    font-size: 0;
}
div:after {
    width: 100%;
    height: 0;
    visibility: hidden;
    overflow: hidden;
    content:'';
    display: inline-block;
}
div > div {
    background: #E76D13;
    width: 100px;
    height: 100px;
    display: inline-block;
    text-align: left;
    border: 1px solid #000;    
    line-height: normal;
    font-size: 14px;
    vertical-align: top;    
}
<div>
    <div>1</div>
   <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
</div>
Dmitriy
  • 4,475
  • 3
  • 29
  • 37
  • 1
    jsfiddle removes some of the unneccesary code and still works: http://jsfiddle.net/f8Lksnmd/9/ - _please_ explain why this works to make an exceptional answer – Toni Leigh Jun 08 '15 at 20:48
  • My problem with this answer is that they will stack on top of each other if there isn't enough space to handle them all horizontally. That may be desired for certain applications, but the Flexbox approach would be better if you absolutely *need* them to stay side-by-side. One way to fix this would be to have another type of div for the spacing, and then using percentages instead of a fixed width. –  Jun 08 '15 at 21:56
1

If you only need to support modern browsers, you can utilize the flexible box layout.

    .parent{
        display:flex;
        justify-content:space-between;
        width: 815px;
        border: solid 1px #aaa;
    }

    .child {
        background-color:yellow;
        width: 100px;
        height: 100px;
        border: solid 1px #ccc;
    }
    <div class="parent">
        <div class="child"></div>
        <div class="child"></div>
        <div class="child"></div>
        <div class="child"></div>
        <div class="child"></div>  
    </div>

Read more about the flexible layout here

To know if your browser supports flexible layout

Maxime Peloquin
  • 915
  • 12
  • 22
1

I know there is already an answer, but for future users I want to make sure they see the correct way to use flexbox. Prefixes are mandatory to use it correctly and responsibly. Without them you will not support IE10, anything before android 4.1 and anything before iOS7. So be careful because flexbox does not degrade well.

Here is a great article on flexbox: https://css-tricks.com/snippets/css/a-guide-to-flexbox/

Here is a great site to check browser compatability: http://caniuse.com/#feat=flexbox

#container {
  display: flex;
  justify-content: space-between;
  border: 1px solid black;
  background: #ccc;
}
#container>div {
  flex: 0 0 100px;
  border: 1px solid black;
  background: #fff;
  height: 100px;
}

/* The order of these prefixed properties is very important!!!  */

#container {
  display: -webkit-box;                       /* OLD - iOS 6-, Safari 3.1-6 */
  display: -moz-box;                          /* OLD - Firefox 19- (buggy but mostly works) */
  display: -ms-flexbox;                       /* TWEENER - IE 10 */
  display: -webkit-flex;                      /* NEW - Chrome */
  display: flex;                              /* NEW, Spec - Opera 12.1, Firefox 20+ */
  -webkit-justify-content:space-between;      /*Chrome */
  justify-content: space-between;             /* NEW, Spec - Opera 12.1, Firefox 20+ */
  border: 1px solid black;
  background: #ccc;
}
#container>div {
    -webkit-box-flex: 0 0 100px;                /* OLD - iOS 6-, Safari 3.1-6 */
  -moz-box-flex: 0 0 100px;                     /* OLD - Firefox 19- */
  width: 20%;                                   /* For old syntax, otherwise collapses. */
  -webkit-flex: 0 0 100px;                      /* Chrome */
  -ms-flex: 0 0 100px;                          /* IE 10 */
  flex: 0 0 100px;                              /* NEW, Spec - Opera 12.1, Firefox 20+ */
  border: 1px solid black;
  background: #fff;
  height: 100px;
}
<div id="container">
  <div>box 1</div>
  <div>box 2</div>
  <div>box 3</div>
  <div>box 4</div>
  <div>box 5</div>
</div>
M H
  • 2,179
  • 25
  • 50
0

You can use margin left but make the first child element have zero margin using css selectors.

    div *{
        display:inline-block;
        /*
        * set your child elements to a set width. If you want them to change
        * size you can use % for the width and adjust this using @media
        */
        margin-left:20px;//use % if you want it to scale.
    }

    div:first-child { 
        margin-left:0px;
    }

<div>
   <div>1</div>
   <div>2</div>
   <div>3</div>
   <div>4</div>
<div>

all the elements will have margin left of 20px except the first one. This will give you a flush line on the left div.

If you don't want the elements to overflow to the next line you can set the parent element to have overflow-x none. And select different widths for the child elements. Bootstrap uses margins and inline-block when it places multiple elements side by side. If you look at bootstrap themes when there placed on a phone the elements switch over to a stack.

see the following link for more about css selectors. http://www.w3schools.com/cssref/sel_firstchild.asp

Patrick W. McMahon
  • 3,488
  • 1
  • 20
  • 31
  • he said no left margin but what is attempting to do is really remove the left margin on the first element. From looking at his demo photos of the elements he just wants to remove the left margin on the first element. Some times what people say and what they mean is not the same. His photos show his true concern. – Patrick W. McMahon Jun 08 '15 at 20:54
  • the problem is when the boxes are removed or more are added, how does the margin respond? – Toni Leigh Jun 08 '15 at 20:55
  • Agreeing with Toni on this. OP is concerned about adaptability. It should support 5, 4, or x number of cells with a set container width. – Joseph Marikle Jun 08 '15 at 20:56
  • that's simply done with % rather then px. or using viewports. – Patrick W. McMahon Jun 08 '15 at 20:57
  • using margin-left is not a bad thing. using it in this situation to have elements side by side and stack when you have a smaller screen is the common way of doing this. He could also get fancy with @media to change the % margin as it scales down. This method will work to stack elements when placed on a phone (this would be the expected behavior on a phone) – Patrick W. McMahon Jun 08 '15 at 21:00
  • OP also says responsiveness is not a concern, however, the problem with margins as far as I can see is that if I remove one block from the answer I don't get three blocks justified, I get three blocks in a line with a large gap on the right - see here: http://jsfiddle.net/okbeo2ba/6/ for what I mean. div * is also a bit greedy, it'll hit everything inside all of the divs too! – Toni Leigh Jun 08 '15 at 21:34
  • in bootstrap they have different % for the number of elements they have. This could be done with this the same. Have a defined class for when you have 3 elements 4 or x amount. Just like bootstrap. – Patrick W. McMahon Jun 08 '15 at 21:42