Last active
December 16, 2015 16:49
-
-
Save jareware/5465928 to your computer and use it in GitHub Desktop.
CSS calc() function.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"/> | |
<meta name="viewport" content="width=device-width, height=device-height"/> | |
<title>CSS calc() function</title> | |
<link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet"> | |
<style type="text/css"> | |
code { | |
color: black; | |
} | |
* { | |
-webkit-box-sizing: border-box; | |
-moz-box-sizing: border-box; | |
box-sizing: border-box; | |
} | |
#example1 { | |
border: 1px solid gray; | |
overflow: hidden; | |
margin-bottom: 10px; | |
} | |
#example1 > div { | |
float: left; | |
text-align: center; | |
background: #CCC; | |
padding: 30px; | |
} | |
#example1 > div:first-child { | |
width: calc(100% - 250px); | |
width: -webkit-calc(100% - 250px); /* for Safari, Blackberry et al */ | |
border-right: 1px dotted gray; | |
} | |
#example1 > div:last-child { | |
width: 250px; | |
} | |
#example2 { | |
border: 1px solid gray; | |
overflow: hidden; | |
padding: 0 0 10px 10px; | |
margin-bottom: 10px; | |
} | |
#example2 > div { | |
float: left; | |
width: calc(100% / 3 - 10px); | |
width: -webkit-calc(100% / 3 - 10px); /* for Safari, Blackberry et al */ | |
border: 1px dotted gray; | |
margin: 10px 10px 0 0; | |
padding: 30px; | |
text-align: center; | |
background: #CCC; | |
} | |
</style> | |
</head> | |
<body class="container"> | |
<h1>CSS calc() function</h1> | |
<p>CSS function for computing values of various types.</p> | |
<ul> | |
<li><a href="https://developer.mozilla.org/en-US/docs/CSS/calc">MDN documentation</a> | |
<li><a href="http://caniuse.com/#search=calc">Browser support</a> | |
<li>Applicable to | |
<code>length</code>, | |
<code>frequency</code>, | |
<code>angle</code>, | |
<code>time</code>, | |
<code>number</code> and | |
<code>integer</code> CSS types | |
<li>Is supposedly nestable, e.g. <code>calc(100% - calc(5em + 1px))</code> should be valid, but didn't work for me | |
<li>Then again standard precedence tools get the job done, so not sure what's the point: <code>calc(100% - (5em + 1px))</code> | |
</ul> | |
<h2>Use cases</h2> | |
<p>You can use <code>calc()</code> to compute between compatible unit types:</p> | |
<pre>calc(10cm + 5mm)</pre> | |
<p>This is a bit silly, because you can do that beforehand, and SASS can also handle it for you:</p> | |
<pre>$ sass -i | |
>> 10cm + 5mm | |
10.5cm</pre> | |
<p>But CSS supports | |
<a href="https://developer.mozilla.org/en-US/docs/CSS/length">two classes of length unit types</a> | |
which are fundamentally incompatible<sup>(asterisk)</sup>: absolute lengths (such as <code>1px</code>) and relative | |
lengths (such as <code>50%</code>): | |
</p> | |
<pre>$ sass -i | |
>> 1px + 1em | |
SyntaxError: Incompatible units: 'em' and 'px'.</pre> | |
<p> | |
This is because <em>relative lengths</em> reference other elements in the DOM (usually the parent node, but also | |
the viewport for example), and they aren't known until <em>render time</em>. | |
</p> | |
<h2>Practical examples</h2> | |
<p> | |
This demonstrates one of the intuitive use cases of being able to calculate between relative and absolute lengths: | |
</p> | |
<div id="example1"> | |
<div>Fluid main container<br>(width: 100% - 250px)</div> | |
<div>Fixed-width sidebar<br>(width: 250px)</div> | |
</div> | |
<p> | |
There's several ways in which the example above can be implemented without <code>calc()</code>, however, for | |
example by absolutely positioning both elements, but it's an intuitive example on where the function's useful. | |
</p> | |
<p> | |
The following, on the other hand, is very hard to do without <code>calc()</code> (or helper elements or flexboxes): | |
</p> | |
<div id="example2"> | |
<div>#1</div> | |
<div>#2</div> | |
<div>#3</div> | |
</div> | |
<p> | |
In the example, the width of each box is relative to the width of the parent, but the padding between them is | |
absolutely <code>10px</code>. | |
</p> | |
<h2>Notes</h2> | |
<ul> | |
<li>Not everything that should conceptually work does, e.g. <code>calc(50vw - 50px)</code> won't fly on Chrome Canary | |
<li> | |
SASS <a href="http://sass-lang.com/docs/yardoc/file.SASS_CHANGELOG.html#_support">won't be bothered</a>, but also Compass won't help | |
<ul> | |
<li>There's a <a href="https://coderwall.com/p/qac-og">mixin</a> for that! | |
<li>Can't be implemented as a <code>@function</code>, because need to output several <code>width:</code> properties | |
<li>Variable expansion won't work directly with <code>width: calc(100% - $padding)</code> but <code>width: calc(100% - #{$padding})</code> sure enough</li> | |
</ul> | |
</li> | |
<!-- TODO: Does this work on Chrome for Android? --> | |
</ul> | |
<!-- TODO: Final word; should you use this? --> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment