3
votes

Can someone please explain to me what calc(.333 * (100vw - 12em)) means in the following line of HTML? And in particular the .333 value; where does that come from?

sizes="(min-width: 36em) calc(.333 * (100vw - 12em)),
       100vw"

Taken from http://ericportis.com/posts/2014/srcset-sizes/

A length can be all sorts of things! A length can be absolute (e.g. 99px, 16em) or relative (33.3vw, as in our example). You’ll note that, unlike our example, there are lots of layouts which combine both absolute and relative units. That’s where the surprisingly well-supported calc() function comes in. Let’s say we added a 12em sidebar to our 3-column layout. We’d adjust our sizes attribute like so:

sizes="(min-width: 36em) calc(.333 * (100vw - 12em)),
       100vw"

I understand this much:

  • (min-width: 36em) = media query
  • calc(.333 * (100vw - 12em)) = rendered image size
  • 100vw = default rendered image length
3

3 Answers

7
votes

Let's dissect this expression:

calc(.333 * (100vw - 12em))

calc means evaluate as an expression.

vw is 1% of the view width, so 100vw is 100% of the view width.

em is the width of the capital m (M), so 12 of those would be the width of 12 ems, or the width of: MMMMMMMMMMMM

100vw - 12em is thus the width minus twelve M's. If this post had a width of the view, then that would be something like:

      / from here                                                         to here \

MMMMMM------------------------------------------------------------------------------MMMMMM

.333 of that is around 1/3, so that would be one third of the width above. So, this width would look something like:

      / from here      to here \                          / or from here  to here \

MMMMMM------------------------------------------------------------------------------MMMMMM

1
votes

Well it means almost exactly one third (0.33...) of (a hundred percent of the viewport's width minus 12em).

Let’s say we added a 12em sidebar to our 3-column layout. We’d adjust our sizes attribute like so...

So, apparently he has a three column layout (hence the 0.33... one third) and he wants to make space for a 12em wide column. So he takes that from the calc()

Hope you got it now.

0
votes

I like to test CSS dimensions with JS, you can thoroughly figure out how relation between values and units works.

var samp = document.getElementById('samp');
var myForm = document.getElementById('myForm');
var output = document.getElementById('output');

myForm.addEventListener('input', function(event){
    var t = event.target;
    t.nextElementSibling.innerHTML = t.value + t.getAttribute('data-unit');
    setWidth();
});

window.onload = function(){
	setWidth();
};

function setWidth(){
    var el = myForm.elements;
	var sheet = document.styleSheets[0];
	var lnh = sheet.cssRules.length;
    var sel = "width: calc(" + el[1].value + " * (" + el[2].value + "vw - " + el[3].value + "em))";
    
	sheet.insertRule("#samp {"+sel+"}", lnh);
    output.innerHTML = sel;
}
input[type='range'] {
  width: 60%;
}

p {
  margin:0;
  font-family:monospace;
}

#samp {
  background-color:#33aaff;
  height:40px;
  margin-top:10px;
}
<form action="" id="myForm">
  <fieldset>
    <label>
      <input type="range" value=".333" min=".1" max="1" step=".001" data-unit="">
      <span>.333</span>
    </label>
    <label>
      <input type="range" value="100" min="1" max="100" step="1" data-unit="vw">
      <span>100vw</span>
    </label>
    <label>
      <input type="range" value="12" min="0" max="50" step=".2" data-unit="em">
      <span>12em</span>
    </label>
  </fieldset>
  <fieldset>
    <p id="output"></p>
  </fieldset>
</form>


<div id="samp"></div>