Skip to content

Instantly share code, notes, and snippets.

@oli
Created December 3, 2012 06:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save oli/4193078 to your computer and use it in GitHub Desktop.
Save oli/4193078 to your computer and use it in GitHub Desktop.
Example 2 — The calc() and attr() functions
/* Example 2 — The calc() and attr() functions */
/* From Beginning HTML5 and CSS3 — The Web Evolved http://thewebevolved.com/ */
body {
width: 80%;
max-width: 42em;
margin: auto;
font: 1em/1.5 Georgia, serif;
}
h1,
h2 {
font-weight: normal;
}
hr,
footer {
margin: 2.5em 0;
}
pre {
-moz-tab-size: 2;
-o-tab-size: 2;
tab-size: 2;
}
pre,
code,
samp,
var {
word-wrap: break-word;
white-space: pre-wrap;
}
figure {
margin-left: 0;
margin-right: 0;
}
figcaption {
clear: left;
padding-top: 1.5em;
}
<h1>Example 2 — The calc() and attr() functions</h1>
<h2>calc()</h2>
<p>With <code>calc()</code> you can instead subtract horizontal <code>margin</code>, <code>border</code> and <code>padding</code> values from the width, for example:</p>
<figure id="calc-example">
<pre class="callout"><code>.content, .sidebar {
float: left;
padding: 1em;
}
.content {width: <mark>calc(100% / 3 * 2 - 1em * 2)</mark>;} /* spaces for “*” and “/” */
.sidebar {
margin-left: 1em;
border-left: 2px solid #999;
width: <mark>calc(100%/3 - 1em - 2px - 1em*2)</mark>; /* no spaces for “*” and “/” */
} </code></pre>
<figcaption>This would give a layout with <code>.content</code> being 2/3 of the page <code>width</code> minus <code>padding</code>, and a <code>.sidebar</code> that’s 1/3 of the page <code>width</code> minus <code>margin</code>, <code>border</code>, and <code>padding</code></figcaption>
</figure>
<p class="callout warning-block">When using the + and - operators make sure they have a space either side, as otherwise they’ll indicate if the following number is positive or negative. Spaces are optional for * and /.</p>
<p>Unlike CSS3 Lists, <a href="http://caniuse.com/#feat=calc"><code>calc()</code> is actually supported</a> in:</p>
<ul>
<li>Firefox: with the vendor prefix <code>-moz-</code> from Firefox 4, and unprefixed from Firefox 16</li>
<li>Internet Explorer 9+ (no prefix)</li>
<li>Chrome 19+, with the vendor prefix <code>-webkit-</code>, and</li>
<li>Safari 6+, with the vendor prefix <code>-webkit-</code></li>
</ul>
<p>So it’s potentially useful in the cascade now, for example:</p>
<pre class="callout"><code>.sidebar {
width: 30%; /* bodge for non-supporting browsers */
width: -webkit-calc(100%/3 - 1em - 2px - 1em*2); /* for Chrome 19+ and Safari 6+ */
width: -moz-calc(100%/3 - 1em - 2px - 1em*2); /* for Firefox 4+ */
width: calc(100%/3 - 1em - 2px - 1em*2; /* for IE 9+ and FF 16+ */
}</code></pre>
<p><a href="http://dev.w3.org/csswg/css3-values/#attr" title="CSS Values and Units Module Level 3">The <code>attr()</code> function</a> (or “attribute reference”) allows you to use the value of an element’s attribute as a value in a CSS property. In CSS 2.1 this could only be used in the <code>content</code> property, but in CSS3 it can be used in almost any property. While the browser will presume units based on the property’s defaults, we can also set the units with a second <code>attr()</code> value, and even include a valid fallback as a third value:</p>
<pre class="callout"><code>.box:after {content: attr(<var>attribute</var>);} /* CSS 2.1 */
.box {width: attr(<var>attribute</var>);} /* CSS3 … */
.box {width: attr(<var>attribute</var>, <var>unit</var>);}
.box {width: attr(<var>attribute</var>, <var>unit</var>, <var>fallback</var>);}</code></pre>
<p>Back in Chapter 4 we discussed HTML5’s new <code>data-*</code> attributes. Combined with <code>attr()</code> these seem a great fit for things like <a href="http://meyerweb.com/eric/thoughts/2009/04/07/findings-of-the-a-list-apart-survey-2008/" title="Eric's Archived Thoughts: Findings of the A List Apart Survey 2008">bar graphs in CSS</a>, rather than the current options of inline styles or classes.</p>
<pre class="callout"><code>.bar {width: attr(data-width);}
.bar {width: attr(data-width, %);}
.bar {width: attr(data-width, %, 100px);} /* fallback can be auto, use different units etc */
&lt;div class="bar" data-width="10"&gt;Widget sales&lt;/div&gt;</code></pre>
<p>Very handy for when you need to style several similar things individually. Sadly while <a href="https://developer.mozilla.org/en/CSS/attr">basic support for <code>attr()</code></a> in the <code>content</code> property is good (modern browsers plus IE8+), there’s no support for <code>attr()</code>’s CSS3 features yet. (Enhancement requests: <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=435426">Firefox</a>, <a href="https://bugs.webkit.org/show_bug.cgi?id=26609">WebKit</a>).</p>
<hr />
<ul>
<li><a href="http://dev.w3.org/csswg/css3-values/" title="CSS Values and Units Module Level 3">CSS Values and Units Module Level 3</a></li>
<li><a href="http://dabblet.com/gist/4193078" title="dabblet.com">This example on Dabblet</a></li>
</ul>
<footer>From <a href="http://thewebevolved.com/"><cite>Beginning HTML5 and CSS3 — The Web Evolved</cite></a>, Chapter 13</footer>
// alert('Hello world!');
{"view":"split","fontsize":"90","seethrough":"","prefixfree":"1","page":"result"}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment