72

I have a layout where I have 3 columns.

Therefore, I divide 100% by 3.

The result is obviously 33.333....

My goal is perfect 1/3 of screen.

Question:

How many numbers after dot can CSS handle to specify 1/3 of width ?

e.g. 33.33333 (n=5) ← how many n can css handle

HTML:

<div id="wrapper">
    <div id="c1"></div>
    <div id="c2"></div>
    <div id="c3"></div>
</div>

CSS:

#c1, #c2, #c3 {
    width: 33%; // 1/3 of 100%
}

Is there a better way to divide by 3?

Patrick Hund
  • 19,163
  • 11
  • 66
  • 95
Ing. Michal Hudak
  • 5,338
  • 11
  • 60
  • 91
  • 5
    You may use 33% for the divs you need and add two additional divs between each two of them, each 0,5% wide. This way, the divs are equally sized and you don't run into floating point problems. – urzeit Sep 13 '13 at 08:34
  • I think this thread will help you. http://stackoverflow.com/questions/4308989/are-the-decimal-places-in-a-css-width-respected – franchez Sep 13 '13 at 08:34
  • 2
    just use 33% two times and for the third 34% - noone will recognize. of course just in case, you want do deviate from your original plan of "perfectness" – Joshua Sep 13 '13 at 08:34
  • 7
    The theoretical precision of CSS is irrelevant: the screen can only draw in whole pixels. –  Sep 13 '13 at 08:35
  • Here's [an interesting post on floating point numbers in CSS](http://stackoverflow.com/a/15300264/1846192). It seems browsers are free to interpret, there isn't really a spec/standard. – Mathijs Flietstra Sep 13 '13 at 08:36
  • Decimal places at lower widths are to bo avoided http://stackoverflow.com/questions/4308989/are-the-decimal-places-in-a-css-width-respected – Kevin Lynch Sep 13 '13 at 08:49
  • I think you should let the browser handle it, and leave the fractions in there (width: 33.33333333%) – TedMeftah Sep 13 '13 at 08:55
  • @Joshua things can get messy, if you design something for a narrow (33%) column, and then it's recomposed in a wide (34%) column. – Markus von Broady Apr 12 '14 at 19:38
  • This [link][1] will help you in best way. [1]: http://stackoverflow.com/questions/10676881/how-to-create-multiple-columns-in-a-div – Abdul Qayyum Apr 24 '15 at 16:19
  • Possible duplicate of [Best way to represent 1/3rd of 100% in CSS?](http://stackoverflow.com/questions/5158735/best-way-to-represent-1-3rd-of-100-in-css) – Paulo Coghi May 18 '16 at 01:38

11 Answers11

133

As it's 2018, use flexbox - no more inline-block whitespace issues:

body {
  margin: 0;
}

#wrapper {
  display: flex;
  height: 200px;
}

#wrapper > div {
  flex-grow: 1;
}

#wrapper > div:first-of-type { background-color: red }
#wrapper > div:nth-of-type(2) { background-color: blue }
#wrapper > div:nth-of-type(3) { background-color: green }
<div id="wrapper">
  <div id="c1"></div>
  <div id="c2"></div>
  <div id="c3"></div>
</div>

Or even CSS grid if you are creating a grid.

body {
  margin: 0;
}

#wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: minmax(200px, auto);
}

#wrapper>div:first-of-type { background-color: red }
#wrapper>div:nth-of-type(2) { background-color: blue }
#wrapper>div:nth-of-type(3) { background-color: green }
<div id="wrapper">
  <div id="c1"></div>
  <div id="c2"></div>
  <div id="c3"></div>
</div>

Use CSS calc():

body {
  margin: 0;
}

div {
  height: 200px;
  width: 33.33%; /* as @passatgt mentioned in the comment, for the older browsers fallback */
  width: calc(100% / 3);
  display: inline-block;
}

div:first-of-type { background-color: red }
div:nth-of-type(2) { background-color: blue }
div:nth-of-type(3) { background-color: green }
<div></div><div></div><div></div>

JSFiddle


References:

TylerH
  • 20,799
  • 66
  • 75
  • 101
Vucko
  • 20,555
  • 10
  • 56
  • 107
  • The problem with this method is it's not supported by anything below IE9. If it's only being use internally on machines running anything that does support it then it's fine. If it's being used in a large scale production it's not. – BenM Sep 13 '13 at 08:51
  • 4
    That's why I put the [caniuse](http://caniuse.com/calc) link. If the OP doesn't need older browser support, `calc` will do just fine ( for a **pure CSS solution**). – Vucko Sep 13 '13 at 08:52
  • I know this solution, just like BenM said, I am looking for more cross-browser solution. For example it will be shown in android aswell, there for I can't use CALC function. But Idea is good. +1 – Ing. Michal Hudak Sep 13 '13 at 12:21
  • 3
    insert width: 33%; before the calc width, if its not supported by the browser, it will fallback to the 33% solution which is almost good. – passatgt Mar 27 '14 at 11:55
  • `display: inline-block` is not good for grid system, if you have space between your divs, last div go to next line. – ghanbari Mar 07 '17 at 09:26
  • @ghanbari see the first link in the reference section. – Vucko Mar 07 '17 at 09:56
  • worked for me in 2020. not sure of cross browser support at point in time of may 2020 but it works in chrome – Matthew Wolman May 05 '20 at 19:33
28

A perfect 1/3 cannot exist in CSS with full cross browser support (anything below IE9). I personally would do: (It's not the perfect solution, but it's about as good as you'll get for all browsers)

#c1, #c2 {
    width: 33%;
}

#c3 {
    width: auto;
}
BenM
  • 4,218
  • 2
  • 31
  • 58
  • 4
    As I wrote above, I'm worried that such solution may produce problems. For example if the column id 33% of a fixed width area, then someone may design text to fit there nicely, but when it's moved to a wider 34% column, the text lines may break in wrong places. – Markus von Broady Apr 12 '14 at 19:42
  • 2
    I don't believe this is the right way to achieve it. Irregularity doesn't feels right to the eye, it makes the difference – Yann Chabot May 01 '15 at 15:14
  • +1 I think it's a "good" solution, i have the same problem and i solved with this. it's just work width some kind of "issue".. for my 3 image it's work pretty good =) But indeed, it's not the correct solution, but it's the easy-short solution – Andrea Bori Feb 20 '16 at 18:54
  • @YannChabot the difference is less noticable if you make the middle one 34% instead of the side ones. It may actually help making the middle ones "pop out" a bit if that's the goal. – NoobishPro Feb 11 '17 at 20:49
  • 2
    @Babydead why not going width: calc(100%/3); ? – Yann Chabot Feb 11 '17 at 23:57
  • @YannChabot yes, I do that. But if you need to support old browsers, that won't work. – NoobishPro Feb 12 '17 at 10:48
  • @Babydead for you browser you can do 33.3333%, and one 33.3334% that would already be better – Yann Chabot Feb 13 '17 at 15:20
  • @YannChabot I tried that before but it gave me a 1px white edge. – NoobishPro Feb 13 '17 at 18:26
  • As far as I know, you can have up to 16 decimals, but doing it with just 2, therefore 33.33%, gets the job done just fine. – VXp Dec 16 '18 at 10:24
24

How about using the CSS3 flex model:

HTML Code:

<div id="wrapper">
    <div id="c1">c1</div>
    <div id="c2">c2</div>
    <div id="c3">c3</div>
</div>  

CSS Code:

*{
    margin:0;
    padding:0;
}

#wrapper{
    display:-webkit-flex;
    -webkit-justify-content:center;

    display:flex;
    justify-content:center;

}

#wrapper div{
    -webkit-flex:1;
    flex:1;
    border:thin solid #777;

}
Dmitri Zaitsev
  • 13,548
  • 11
  • 76
  • 110
bring2dip
  • 886
  • 2
  • 11
  • 22
  • This has the horrible side-effect that when you're working with rows and you end up with an uneven number, it'll stretch the last row to 100% :) – NoobishPro Feb 11 '17 at 20:50
10

Using this fiddle, you can play around with the width of each div. I've tried in both Chrome and IE and I notice a difference in width between 33% and 33.3%. I also notice a very small difference between 33.3% and 33.33%. I don't notice any difference further than this.

The difference between 33.33% and the theoretical 33.333...% is a mere 0.00333...%.

For arguments sake, say my screen width is 1960px; a fairly high but common resolution. The difference between these two widths is still only 0.065333...px.

So, further than two decimal places, the difference in precision is negligible.

Connell
  • 13,925
  • 11
  • 59
  • 92
9
.selector{width:calc(100% / 3);}
Kodek
  • 169
  • 3
  • 12
8

In case you wonder, In Bootstrap templating system (which is very accurate), here is how they divide the columns when you apply the class .col-md-4 (1/3 of the 12 column system)

CSS

.col-md-4{
    float: left;
    width: 33.33333333%;
}

I'm not a fan of float, but if you really want your element to be perfectly 1/3 of your page, then you don't have a choice because sometimes when you use inline-block element, browser can consider space in your HTML as a 1px space which would break your perfect 1/3. Hope it helped !

Dmitri Zaitsev
  • 13,548
  • 11
  • 76
  • 110
Yann Chabot
  • 4,789
  • 3
  • 39
  • 56
6

Just in case someone is still looking for the answer,

let the browser take care of that. Try this:

  • display: table on the container element.
  • display: table-cell on the child elements.

The browser will evenly divide it whether you have 3 or 10 columns.

EDIT

the container element should also have: table-layout: fixed otherwise the browser will determine the width of each element (most of the time not that bad).

JMRC
  • 1,473
  • 1
  • 17
  • 36
2

Just to present an alternative way to fix this problem (if you don't really care about supporting IE):

A soft coded solution would be to use display: table (no support in IE7) along with table-layout: fixed (to ensure equal width columns).

Read more about this here.

Community
  • 1
  • 1
Jean-Paul
  • 19,910
  • 9
  • 62
  • 88
2

I have found that 6 decimal places is sometimes required (at least in Chrome) for the 1/3 to return a perfect result.

E.g., 1140px / 3 = 380px

If you had 3 elements within the 1140 container, they would need to have a width set to 33.333333% before Chrome's inspector tool shows that they are at 380px. Any less amount of decimal places, and Chrome returns a lesser width of 379.XXXpx

Garconis
  • 773
  • 11
  • 31
2

2018 Update This is the method I use width: 33%; width: calc(33.33% - 20px); The first 33% is for browsers that do not support calc() inside the width property, the second would need to be vendor prefixed with -webkit- and -moz- for the best possible cross-browser support.

#c1, #c2, #c3 {
    margin: 10px; //not needed, but included to demonstrate the effect of having a margin with calc() widths/heights
    width: 33%; //fallback for browsers not supporting calc() in the width property
    width: -webkit-calc(33.33% - 20px); //We minus 20px from 100% if we're using the border-box box-sizing to account for our 10px margin on each side.
    width: -moz-calc(33.33% - 20px);
    width: calc(33.33% - 20px);
}

tl;dr account for your margin

brandito
  • 698
  • 8
  • 19
1

I do not think you can do it in CSS, but you can calculate a pixel perfect width with javascript. Let's say you use jQuery:

HTML code:

<div id="container">
   <div id="col1"></div>
   <div id="col2"></div>
   <div id="col3"></div>
</div>

JS Code:

$(function(){
   var total = $("#container").width();
   $("#col1").css({width: Math.round(total/3)+"px"});
   $("#col2").css({width: Math.round(total/3)+"px"});
   $("#col3").css({width: Math.round(total/3)+"px"});
});
Scalpweb
  • 1,971
  • 1
  • 12
  • 14
  • If the container width was 100px then this still wouldnt work as as Mike W pointed out you can only measure in full pixels. – BenM Sep 13 '13 at 08:45
  • I said "pixel perfect". Of course you will never be able to cut a pixel in 3... But with this solution, each divs will have the same maximal width. – Scalpweb Sep 13 '13 at 08:47
  • Ahh my understanding of pixel perfect was wrong then! I get what you mean now. – BenM Sep 13 '13 at 08:47
  • This would also cause them to wrap on occasion when the `.round`ing goes up.`.floor` would prevent this. – Brook Jordan May 17 '16 at 05:18
  • div's are block level element's, so we need to make them inline block first – zakir Jan 25 '18 at 13:33
  • what the hell kind of abomination is this, js to control css? – brandito May 30 '18 at 06:54