201

In CSS, how can I do something like this:

width: 100% - 100px;

I guess this is fairly simple but it is a bit hard to find examples showing that.

GEOCHET
  • 21,119
  • 15
  • 74
  • 98
fmsf
  • 36,317
  • 49
  • 147
  • 195
  • 1
    The linked question http://stackoverflow.com/questions/11093943/is-it-possible-to-make-a-div-50px-less-than-100-in-css?newsletter=1&nlcode=78829%7c765d gives an interesting, but not fully backward compatible answer, maybe you would like to take a look on that too. – 11684 Jun 19 '12 at 19:23
  • 9
    For anyone who crosses this question Chad answered that modern browsers supports `width: calc(100% - 100px);` it's a few answers down and I hope the asker will update his question :) :) – Anders M. May 05 '14 at 14:20

18 Answers18

361

Modern browsers now support the:

width: calc(100% - 100px);

To see the list of supported browser versions checkout: Can I use calc() as CSS unit value?

There is a jQuery fallback: css width: calc(100% -100px); alternative using jquery

Community
  • 1
  • 1
Chad
  • 3,743
  • 1
  • 15
  • 10
  • 15
    I found when I was using `calc(100% - 6px)` for example it was displaying as `calc(94%)`, I had to escape it as follows and now it works `width: calc(~"100% - 6px");` – nsilva Apr 19 '16 at 12:53
  • 26
    Be aware, you must have whitespace around the `-` (or `+`) character. This works: `calc(100% - 100px);` And this doesn't: `calc(100%-100px);` – freefaller Mar 24 '17 at 16:19
  • I'm a little surprised there's no option to automatically subtract 2x the padding of the element, which would usually be a pretty common usecase. E.g., I end up having to do `padding: 0.25em; width: calc(100% - 2 * 0.25em - 2em);`, and would have to change the `0.25em` in two places now if it has to be amended. – cnst Sep 08 '19 at 22:23
  • So many thanks, would also like to note that it works for addition: (100% + 100px) – Viktor Mellgren Nov 14 '19 at 10:28
100

Could you nest a div with margin-left: 50px; and margin-right: 50px; inside a <div> with width: 100%;?

Bob
  • 5,510
  • 9
  • 48
  • 80
Aric TenEyck
  • 8,002
  • 1
  • 34
  • 48
21

You can try this...

<!--First Solution-->
width: calc(100% - 100px);
<!--Second Solution-->
width: calc(100vh - 100px);

vw: viewport width

vh: viewport height

barış çıracı
  • 1,033
  • 14
  • 16
  • First solution is correct, the container might not be the window and therefore 100vh might not equal 100% – Ben Taliadoros Mar 02 '16 at 14:18
  • 2
    I found when I was using `calc(100% - 6px)` for example it was displaying as `calc(94%)`, I had to escape it as follows and now it works `width: calc(~"100% - 6px");` – nsilva Apr 19 '16 at 12:52
7

It started to work for me only when I checked all the spaces. So, it didn't work like this: width: calc(100%- 20px) or calc(100%-20px) and perfectly worked with width: calc(100% - 20px).

Matthew Strawbridge
  • 19,940
  • 10
  • 72
  • 93
4

my code, and it works for IE6:

<style>
#container {margin:0 auto; width:100%;}
#header { height:100px; background:#9c6; margin-bottom:5px;}
#mainContent { height:500px; margin-bottom:5px;}
#sidebar { float:left; width:100px; height:500px; background:#cf9;}
#content { margin-left:100px; height:500px; background:#ffa;}

</style>

<div id="container">
  <div id="header">header</div>
  <div id="mainContent">
    <div id="sidebar">left</div>
    <div id="content">right 100% - 100px</div>
  <span style="display:none"></span></div>
</div>

enter image description here

Nikunj Madhogaria
  • 2,139
  • 2
  • 23
  • 40
andrewchan2022
  • 4,953
  • 45
  • 48
4

You need to have a container for your content div that you wish to be 100% - 100px

#container {
   width: 100%
}
#content {
   margin-right:100px;
   width:100%;
}

<div id="container">
  <div id="content">
      Your content here
  </div>
</div>

You might need to add a clearing div just before the last </div> if your content div is overflowing.

<div style="clear:both; height:1px; line-height:0">&nbsp;</div>
aleemb
  • 31,265
  • 19
  • 98
  • 114
2

Working with bootstrap panels, I was seeking how to place "delete" link in header panel, which would not be obscured by long neighbour element. And here is the solution:

html:

<div class="with-right-link">
    <a class="left-link" href="#">Long link header Long link header</a>
    <a class="right-link" href="#">Delete</a>
</div>

css:

.with-right-link { position: relative; width: 275px; }
a.left-link { display: inline-block; margin-right: 100px; }
a.right-link { position: absolute; top: 0; right: 0; }

Of course you can modify "top" and "right" values, according to your indentations. Source

Artur Loginov
  • 131
  • 2
  • 4
2

Setting the body margins to 0, the width of the outer container to 100%, and using an inner container with 50px left/right margins seems to work.

<style>
body {
    margin: 0;
    padding: 0;
}

.full-width
{
    width: 100%;
}

.innerContainer
{
    margin: 0px 50px 0px 50px;
}
</style>

<body>
  <div class="full-width" style="background-color: #ff0000;">
    <div class="innerContainer" style="background-color: #00ff00;">
      content here
    </div>
  </div>
</body>
tvanfosson
  • 524,688
  • 99
  • 697
  • 795
1

There are 2 techniques which can come in handy for this common scenario. Each have their drawbacks but can both be useful at times.

box-sizing: border-box includes padding and border width in the width of an item. For example, if you set the width of a div with 20px 20px padding and 1px border to 100px, the actual width would be 142px but with border-box, both padding and margin are inside the 100px.

.bb{
    -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
    -moz-box-sizing: border-box;    /* Firefox, other Gecko */
    box-sizing: border-box;     
    width: 100%;
    height:200px;
    padding: 50px;
}

Here's an excellent article on it: http://css-tricks.com/box-sizing/ and here's a fiddle http://jsfiddle.net/L3Rvw/

And then there's position: absolute

.padded{
    position: absolute;
    top: 50px;
    right: 50px;
    left: 50px;
    bottom: 50px;
    background-color: #aefebc;
}

http://jsfiddle.net/Mw9CT/1/

Neither are perfect of course, box-sizing doesn't exactly fit the question as the element is actually 100% width, rather than 100% - 100px (however a child div would be). And absolute positioning definitely can't be used in every situation, but is usually okay as long as the parent height is set.

Dave
  • 1,409
  • 2
  • 18
  • 14
1

Could you do:

margin-right: 50px;
margin-left: 50px;

Edit: My solution is wrong. The solution posted by Aric TenEyck suggesting using a div with width 100% and then nesting another div using the margins seems more correct.

Tina Orooji
  • 1,842
  • 3
  • 15
  • 14
  • 3
    If you do this, won't you end up with the total width being 100% + 100px? – Adam Crume May 22 '09 at 17:58
  • :o( I'm sorry. Should I delete my post or should I leave it and let the down votes push it down? – Tina Orooji May 22 '09 at 18:05
  • 1
    down votes are usually meant to encourage you to clean up your post so you can regain rep points lost by the negative votes. If you know your solution to be wrong you can delete if with or without down votes or update it to make it right. – aleemb May 22 '09 at 18:14
  • @AdamCrume - Nope. That would only be the case if you also specified `width:100%`. A div will automatically fill the container unless you override that, eg, by explicitly specifying `width`, or by using `float` or absolute positioning. Adding a margin to a div will just cause it to fill its container, less the amount specified by the margin. – gilly3 Jun 19 '12 at 16:37
  • @aleemb - In this case the downvotes are by users who don't understand css as this answer is perfectly correct. – gilly3 Jun 19 '12 at 16:38
  • @fmsf - If this solution isn't working, it's because you are doing something more to your div. Do you also have `width: 100%` on this div? Are you using `float`? – gilly3 Jun 19 '12 at 16:39
  • @Tina - Your answer is 100% correct, and a more elegant solution than Aric's because it doesn't require modifying the markup. There already is a parent element, so adding a separate div is redundant. A div automatically expands to fill its container so specifying `width:100%` is unnecessary and actually causes bad side effects. – gilly3 Jun 19 '12 at 16:40
1

Padding on the outer div will get the desired effect.

<html>
<head>
<style>
    #outer{
        padding: 0 50px;
        border:1px solid black; /*for visualization*/
    }

    #inner{
        border:1px solid red; /*for visualization*/
    }
</style>
</head>
<body>
<div id="outer">
    <div id="inner">
        100px smaller than outer
    </div>
</div>
</body>
</html>
Josh Bush
  • 2,708
  • 4
  • 24
  • 25
0

You can look into using LESS, which is a JavaScript file that pre-processes your CSS so you can include logic and variables into your CSS. So for your example, in LESS you would write width: 100% - 100px; to achieve exactly what you wanted :)

Jon
  • 8,205
  • 25
  • 87
  • 146
0
<div style="width: 200px; border: 1px solid red;">
    <br>
    <div style="margin: 0px 50px 0px 50px; border: 1px solid blue;">
        <br>
    </div>
    <br>
</div>
Derek 朕會功夫
  • 92,235
  • 44
  • 185
  • 247
RC.
  • 27,409
  • 9
  • 73
  • 93
0

Are you using standards mode? This solution depends on it I think.

If you're trying to make 2 columns you could do something like this:

<div id="outer">
    <div id="left">
        sidebar
    </div>
    <div id="main">
        lorem ispsum etc... 
    </div>
</div>

Then use CSS to style it:

div#outer
{
    width:100%;
    height: 500px;
}

div#left
{
    width: 100px;
    height: 100%;
    float:left;
    background: green;
}

div#main
{
   width: auto;
   margin-left: 100px; /* same as div#left width */
   height: 100%;
   background:red;
}

If you don't want 2 columns you can probably remove <div id="left">

hannson
  • 4,465
  • 8
  • 38
  • 46
-1

CSS can not be used to animation, or any style modification on events.

The only way is to use a javascript function, which will return the width of a given element, then, subtract 100px to it, and set the new width size.

Assuming you are using jQuery, you could do something like that:

oldWidth = $('#yourElem').width();
$('#yourElem').width(oldWidth-100);

And with native javascript:

oldWidth = document.getElementById('yourElem').clientWidth;
document.getElementById('yourElem').style.width = oldWidth-100+'px';

We assume that you have a css style set with 100%;

Boris Guéry
  • 47,316
  • 8
  • 52
  • 87
-2

This works:

margin-right:100px;
width:auto;
Michał Perłakowski
  • 88,409
  • 26
  • 156
  • 177
-3

You can't.

You can, however, use margins to effect the same result.

Traingamer
  • 1,438
  • 8
  • 9
-6

The short answer is you DON'T do this in CSS. Internet Explorer has support for something called CSS Expressions, but this isn't standard and is definitely not supported by other browsers like FireFox for instance.

You'd be better off doing this in JavaScript.

Praveen Angyan
  • 7,227
  • 29
  • 34
  • Yeah guess I'll have to do keep it in javascript, I'm refractoring some code and wanted to remove the javascript that was doing that tks. – fmsf May 22 '09 at 18:00
  • 2
    *Please* if you can avoid it don't do this in JavaScript. HTML+CSS may be tricky and the solution may not be obvious, but it can likely do almost anything you need. Using JavaScript for static layouts is almost always a bad idea. – Nicole Jan 21 '10 at 22:56
  • Maybe the answer made some sense in '09, but DON'T do it in JavaScript in '20 – Mark Kahn Sep 09 '20 at 17:02