Eminence
Eminence

Reputation: 288

Why doesn't the CSS calc() function work for me?

I learned about the CSS function calc() and its awesome. I tried to use it like:

#abc {
  width: calc(100%-120px);
  height: 50px;
  background: black;
}
<div id="abc"></div>

But the problem with this function is that it doesn't work. I tested this code IE9 and Safari and it didn't work.

Why doesn't it work?

Upvotes: 27

Views: 62669

Answers (8)

Jukka K. Korpela
Jukka K. Korpela

Reputation: 201538

The operator - must be surrounded by spaces:

#abc {
  width: calc(100% - 120px);
  height: 50px;
  background: black;
}
<div id="abc"></div>

Quoting MDN info on calc():

Note: The + and - operators must be surrounded by whitespace. For instance, calc(50% -8px) will be parsed as a percentage followed by a negative length—an invalid expression—while calc(50% - 8px) is a percentage followed by a subtraction operator and a length. Likewise, calc(8px + -50%) is treated as a length followed by an addition operator and a negative percentage.

The * and / operators do not require whitespace, but adding it for consistency is both allowed and recommended.

The formal statement on this is in clause 8.1.1 of the CSS Values and Units Module Level 3 specification.

Upvotes: 61

Nesha Zoric
Nesha Zoric

Reputation: 6620

In order for your function to work you need to have spaces between the operator sign.

For example:

#abc{
  width: calc(100% - 20px)
}

The calc() article provides a further detailed explanation of the issue.

Upvotes: 2

B-GangsteR
B-GangsteR

Reputation: 2704

First of all, there should be spaces before and after + or -. You can also use * , /, and combine them. See example:

.gen {
  height: 100px;
  background-color: blue;
  border: solid 1px black;
}

.nocalc {
  width: 50%;
}

.calc {
  width: calc(100% / 4 * 2 + 50px - 40px); 
  /* 50% + 10px */
}
<div class="gen nocalc"></div>
<div class="gen calc"></div>

It works with display: table, but it does not work with display: table-row(row takes whole space) and does not work with display: table-cell (if one cell it takes whole space; if several - each cell takes space according to its content).

.cont-1 {
  background-color: yellow;
}

.cont-2 {
 background-color: red;
 border: solid 1px black;
}

.width-m-50 {
  width: calc(100% - 20px);
  height: 100px;
}

.tab-simple {
  display: table;
}

.tab {
  display: table;
  border: solid 1px black;
  background-color: yellow;
  width: 100%;
}

.tab-row {
  display: table-row;
}

.tab-cell {
  display: table-cell;
}
<div class="cont-1"> 
  <div class="cont-2 width-m-50"> 
    div with width: calc(100% - 20px);
  </div>
</div>

<div class="cont-1"> 
  <div class="cont-2 tab-simple width-m-50"> 
    tab with width: calc(100% - 20px);
  </div>
</div>
<h3> tab with width 100% and two cells, 1-st with width calc(100% - 20px); 2-nd without: </h3>
<div class="tab">
  <div class="tab-row"> 
      <div class="cont-2 tab-cell width-m-50"> 
        cell
      </div>
      <div class="cont-2 tab-cell"> 
        cell 
      </div>
  </div>
</div>

Upvotes: 1

Vasil Enchev
Vasil Enchev

Reputation: 1726

You need spaces and also if you use preprocessor format it like this calc(~"100% - 20px") or it might not work.

Upvotes: 0

Kevin Beal
Kevin Beal

Reputation: 10849

IE9's implementation of the calc() method doesn't work on elements which are display: table.

You can work around this by wrapping a div around it (which is display: block) and making the width of the display: table element inside width: 100%. You apply the calcd width to the surrounding div.

Upvotes: 4

Benjamin
Benjamin

Reputation: 8248

With the latest version of Modernizr you can check csscalc support. Simply use Modernizr.csscalc. This function will return true if it is supported and false if it isn't. In your case you would have this in your css :

#abc {  width:calc(100% - 20px); }

and in your javascript (I am using jQuery here)

if(!Modernizr.csscalc){
    $('#abc').width($(PARENT_EL).width() - 20)
}

BTW. It is better to style your elements with class names rather than ID. The ID of an element should only be used to target it through javascript.

Upvotes: 0

Shenba
Shenba

Reputation: 189

All the modern browsers except Android's native browser support calc() which makes it easier to adopt. But do note that it can have a big impact on the layout and the consequent breaking of your design on unsupported browsers.

You should use it with a fallback declaration, so it doesn't break browsers which don't support it.

width: 500px; /** older browsers **/ 

width: -webkit-calc(50% - 20px); /** Safari 6, Chrome 19-25 **/

width: -moz-calc(50% - 20px); /** FF 4-15  **/

width: calc(50% - 20px); /** FF 16+, IE 9+, Opera 15, Chrome 26+, Safari 7 and future other browsers **/

Upvotes: 18

MarcinJuraszek
MarcinJuraszek

Reputation: 125620

It is supported by IE9, IE10 and Safari 6.0 (using -webkit- prefix). You can check whole support table here: http://caniuse.com/#feat=calc

Upvotes: 5

Related Questions