12

I wonder if there is way to set outerwidth of a div using css to ignore padding and borders.

When I set a div to be 50% width, padding and border will be added to the width. How can I solve that without javascript or jQuery.outerWidth() ?

Don't want to use an extra element

Omid
  • 3,903
  • 8
  • 36
  • 65
  • That's the way the box model works on modern browsers. Using percentages in sizing assumes the width will be relative to other content. If you want to better control the exact width, you will have to use pixel sizing, taking into account the padding, border, and margin widths. – samuelg Jun 06 '12 at 15:14
  • Using pixel will solve the problem but i have to use percent. – Omid Jun 06 '12 at 15:16
  • 1
    If you have control over the markup and you don't care about "dirty" markup, you will find a lot of answers along the lines of http://stackoverflow.com/questions/651317/div-width-100-minus-fixed-amount-of-pixels – mawcsco Jun 06 '12 at 15:17

5 Answers5

24

I'm wonder if there is way to set outerwidth of a div using css to ignore padding and borders.

You can use box-sizing: border-box to make padding and border be counted inside width:

div {
    box-sizing: border-box;
}

See: http://jsfiddle.net/thirtydot/6xx3h/

Browser support: http://caniuse.com/css3-boxsizing

The spec: http://www.w3.org/TR/css3-ui/#box-sizing

thirtydot
  • 210,355
  • 44
  • 377
  • 337
  • I think this is probably the best answer to the OP. – mawcsco Jun 06 '12 at 17:35
  • It's seems what i need, but how about IE versions that not support css3 ? – Omid Jun 07 '12 at 05:53
  • 1
    @OmidAmraei: There are a few options. You can use a JavaScript polyfill: https://github.com/Schepp/box-sizing-polyfill. If that's not desirable, you have to use two elements, as in Mr. TA's answer. You have to pay a price to support an old browser such as IE7. Alternatively, if it doesn't have to be *perfect* in IE7, you can use `width: 50%; *width: 45%;`, which will make the `div` have 45% width in only IE7 and lower, which might be good enough. – thirtydot Jun 07 '12 at 08:44
3

Nest another div inside yours, and apply the paddings/borders to the nested one:

<div style="width:50%;"> <div style="padding:5px;">  ....  </div> </div>

Unfortunately, there is no purely CSS way to achieve that (or at least I'm not aware of one).

Mr. TA
  • 4,776
  • 24
  • 32
  • Don't want to add another extra element – Omid Jun 06 '12 at 15:15
  • This is the most common solution to this problem. However, this approach "dirties" the mark-up and may not always be possible. I'd be curious to see how to solve this problem in the realm of CSS and not markup. – mawcsco Jun 06 '12 at 15:16
  • 1
    There is no "clean" solution, since W3C are a bunch of idiots who can't manage to make a decent spec. MS IE, btw, used the "outer width" approach in CSS, until they were forced to follow the standards (even though standards were poorly written). – Mr. TA Jun 06 '12 at 15:19
  • Your whining is unjustified. See [my answer](http://stackoverflow.com/questions/10917049/set-div-outerwidth-using-css/10917753#10917753). Here's the spec for `box-sizing`: http://www.w3.org/TR/css3-ui/#box-sizing – thirtydot Jun 06 '12 at 15:57
  • Good news. Doesn't undo the fact, however, that they are idiots since it took them 12 years to bring back functionality which was available in IE 5.5 in 2000. Functionality, btw, which is arguably more useful than the "inner width" approach. But this is not a platform to argue that point. :) – Mr. TA Jun 06 '12 at 16:26
1

I am assuming you don't want to add more elements and answer your question slightly differently.

  1. The browser, not the style-sheet, determines the actual size of relative measurements such as em and %.
  2. There is no common/standard mechanism to feed calculated data from the browser's internal layout engine back into a stylesheet (this could be a dangerous looping problem).

Truly, the only way to do this is to:

  1. Use fixed width sizes and add pixel calculations into your style.
  2. Use JavaScript or related framework to achieve the results.
mawcsco
  • 604
  • 6
  • 18
  • using js to fix your css is not the optimal solution and doesn't degrade with js off – Luca Jun 06 '12 at 15:42
  • @luca I never said it was "optimal." In fact, it downright sucks. I'm just being realistic based on the question posed. – mawcsco Jun 06 '12 at 17:32
  • I did not know about box-sizing mentioned by @thirtydot. That looks like the answer. – mawcsco Jun 06 '12 at 17:34
  • @mawcsco my comment was just to complete your answer as you did not mention about the downsides - no need to take it personally – Luca Jun 06 '12 at 22:28
0

I would simply add a div inside that div if possible.

<div id="outerwidth">
  <div class="inner">
   //Content
  </div>
</div>

.outerwidth { width: 50%; }
.inner { padding: 20px; }
chadpeppers
  • 1,938
  • 1
  • 17
  • 27
  • Don't want to add another extra element – Omid Jun 06 '12 at 15:15
  • 3
    Only other option i know is to use % in your padding and borders also but they will expand as the browser does. So if your width is 48%, border 1%, and padding is 1%, will equal to 50% – chadpeppers Jun 06 '12 at 15:19
  • @Chad good idea. Not sure that's what the asker was looking for, but nonetheless. – Mr. TA Jun 06 '12 at 15:20
  • @Chad Seems good idea, but unfortunately can make unexpected results – Omid Jun 06 '12 at 15:24
0

you could split the 50% value assigned to the width as this:

width: 46%;

margin: 0 1%; // 0 top/bottom and 1% each for left and right

padding: 0 1%; // same as above

you can recalculate the percentages to suit your needs, as long as the total is 50% you should be fine.

I would avoid using js to fix small cosmetic issues as this would not work with js off and would add extra workload to your client's browser - think of mobile and you will see why performance counts!

Luca
  • 7,571
  • 5
  • 41
  • 56