Showing preview only (796K chars total). Download the full file or copy to clipboard to get everything.
Repository: adamschwartz/magic-of-css
Branch: gh-pages
Commit: 066aa596b420
Files: 68
Total size: 766.2 KB
Directory structure:
gitextract_ajwg6exb/
├── .gitignore
├── 404.html
├── LICENSE.md
├── README.md
├── chapters/
│ ├── 1-the-box/
│ │ ├── images/
│ │ │ └── box-model.sketch/
│ │ │ ├── Data
│ │ │ ├── metadata
│ │ │ └── version
│ │ └── index.html
│ ├── 2-layout/
│ │ └── index.html
│ ├── 3-tables/
│ │ └── index.html
│ ├── 4-color/
│ │ └── index.html
│ ├── 5-typography/
│ │ └── index.html
│ ├── 6-transitions/
│ │ └── index.html
│ ├── _template.html
│ └── preface/
│ └── index.html
├── config.rb
├── css/
│ ├── base.css
│ ├── chapter.css
│ ├── eager.css
│ ├── home.css
│ ├── logo.css
│ ├── potions.css
│ └── social.css
├── fool-github/
│ ├── css.css
│ └── more-css.css
├── index.html
├── js/
│ ├── chapters.coffee
│ ├── chapters.js
│ ├── footer.coffee
│ ├── footer.js
│ ├── home.coffee
│ └── home.js
├── magician-helpers/
│ └── blackboard/
│ └── index.html
├── planning/
│ └── planning.md
├── potions/
│ ├── buttons/
│ │ └── index.html
│ ├── content-reordering/
│ │ └── index.html
│ ├── letter-spacing/
│ │ └── index.html
│ ├── overflow-ellipsis/
│ │ ├── config.rb
│ │ ├── css/
│ │ │ └── overflow-ellipsis.css
│ │ ├── index.html
│ │ └── sass/
│ │ └── overflow-ellipsis.sass
│ ├── potpourri/
│ │ └── index.html
│ ├── table-styling/
│ │ ├── config.rb
│ │ ├── css/
│ │ │ └── table-styling.css
│ │ ├── index.html
│ │ └── sass/
│ │ └── table-styling.sass
│ ├── three-pane-app/
│ │ ├── config.rb
│ │ ├── css/
│ │ │ └── three-pane-app.css
│ │ ├── index.html
│ │ └── sass/
│ │ └── three-pane-app.sass
│ ├── three-pane-app-with-color/
│ │ ├── config.rb
│ │ ├── css/
│ │ │ └── three-pane-app-with-color.css
│ │ ├── index.html
│ │ └── sass/
│ │ └── three-pane-app-with-color.sass
│ └── two-pane-app/
│ ├── config.rb
│ ├── css/
│ │ └── two-pane-app.css
│ ├── index.html
│ └── sass/
│ └── two-pane-app.sass
└── sass/
├── _colors.sass
├── _rainbow.sass
├── _variables.sass
├── base.sass
├── chapter.sass
├── eager.sass
├── home.sass
├── logo.sass
├── potions.sass
└── social.sass
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
.sass-cache
================================================
FILE: 404.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Page not found — Magic of CSS — Adam Schwartz</title>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<link rel="icon" href="/magic-of-css/favicon.ico">
<link rel="stylesheet" href="/magic-of-css/css/base.css">
<link rel="stylesheet" href="/magic-of-css/css/logo.css">
<style>body { padding: 8em 2em }</style>
</head>
<body>
<div class="page">
<a class="logo" href="/magic-of-css"><h1 class="the-magic-of">The Magic of CSS</h1><div class="css-rainbow"><div class="css-letter css-rainbow-c"><div class="rainbow"><div class="bands"><div class="red"></div><div class="orange"></div><div class="yellow"></div><div class="green"></div><div class="blue"></div><div class="purple"></div></div></div></div><div class="css-letter css-rainbow-s css-rainbow-s-1"><div class="top-half"><div class="rainbow"><div class="bands"><div class="red"></div><div class="orange"></div><div class="yellow"></div><div class="green"></div><div class="blue"></div><div class="purple"></div></div></div></div><div class="bottom-half"><div class="rainbow"><div class="bands"><div class="purple"></div><div class="blue"></div><div class="green"></div><div class="yellow"></div><div class="orange"></div><div class="red"></div></div></div></div></div><div class="css-letter css-rainbow-s css-rainbow-s-2"><div class="top-half"><div class="rainbow"><div class="bands"><div class="red"></div><div class="orange"></div><div class="yellow"></div><div class="green"></div><div class="blue"></div><div class="purple"></div></div></div></div><div class="bottom-half"><div class="rainbow"><div class="bands"><div class="purple"></div><div class="blue"></div><div class="green"></div><div class="yellow"></div><div class="orange"></div><div class="red"></div></div></div></div></div></div></a>
</div>
</body>
</html>
================================================
FILE: LICENSE.md
================================================
Copyright © 2014 Adam Schwartz
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: README.md
================================================
## The Magic of CSS
> A CSS course for web developers who want to be magicians.
- [The Magic of CSS](http://adamschwartz.co/magic-of-css)
- [Preface](http://adamschwartz.co/magic-of-css/chapters/preface)
- [Chapter 1: The Box](http://adamschwartz.co/magic-of-css/chapters/1-the-box)
- [Chapter 2: Layout](http://adamschwartz.co/magic-of-css/chapters/2-layout)
- [Chapter 3: Tables](http://adamschwartz.co/magic-of-css/chapters/3-tables)
- [Chapter 4: Color](http://adamschwartz.co/magic-of-css/chapters/4-color/)
- [Chapter 5: Typography](http://adamschwartz.co/magic-of-css/chapters/5-typography)
- [Chapter 6: Transitions](http://adamschwartz.co/magic-of-css/chapters/6-transitions/)
- See [planning.md](https://github.com/adamschwartz/magic-of-css/blob/gh-pages/planning/planning.md) for what’s next...
================================================
FILE: chapters/1-the-box/images/box-model.sketch/metadata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>app</key>
<string>com.bohemiancoding.sketch</string>
<key>build</key>
<integer>5355</integer>
<key>commit</key>
<string>b7d299b0a34651d1a0e066786b75aa36168d5809</string>
<key>fonts</key>
<array>
<string>Monaco</string>
<string>Monaco</string>
<string>Monaco</string>
<string>Monaco</string>
</array>
<key>length</key>
<integer>23101</integer>
<key>version</key>
<integer>18</integer>
</dict>
</plist>
================================================
FILE: chapters/1-the-box/images/box-model.sketch/version
================================================
18
================================================
FILE: chapters/1-the-box/index.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>The Box — Chapter 1 — Magic of CSS — Adam Schwartz</title>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<link rel="icon" href="/magic-of-css/favicon.ico">
<link rel="stylesheet" href="../../css/base.css">
<link rel="stylesheet" href="../../css/logo.css">
<link rel="stylesheet" href="../../css/chapter.css">
<script src="../../js/chapters.js"></script>
</head>
<body>
<div class="page">
<a class="logo" href="/../.."><h1 class="the-magic-of">The Magic of CSS</h1><div class="css-rainbow"><div class="css-letter css-rainbow-c"><div class="rainbow"><div class="bands"></div></div></div><div class="css-letter css-rainbow-s css-rainbow-s-1"><div class="top-half"><div class="rainbow"><div class="bands"></div></div></div><div class="bottom-half"><div class="rainbow"><div class="bands"></div></div></div></div><div class="css-letter css-rainbow-s css-rainbow-s-2"><div class="top-half"><div class="rainbow"><div class="bands"></div></div></div><div class="bottom-half"><div class="rainbow"><div class="bands"></div></div></div></div></div></a>
<div class="chapter">
<h1>
<span class="number">Chapter 1</span>
<span class="title">The Box</span>
</h1>
<h2>Box model</h2>
<p>In CSS, the <a href="http://www.w3.org/TR/CSS2/box.html">box model</a><sup><a href="#cite-1">[1]</a></sup> describes the rectangular boxes that are generated for elements laid out in the page.</p>
<p>Essentially, everything is a rectangle.</p>
<figure>
<img src="images/box-model.svg">
<figcaption>
<div class="figcaption">
A picture of the box model<sup><a href="#cite-1">[1]</a></sup>
</div>
</figcaption>
</figure>
<p>Some interesting facts:</p>
<ul>
<li><code>border-radius</code> rounds out the corners of this box.</li>
<li><code>box-shadow</code> adds a shadow to this box.</li>
<li><code>outline</code> and <code>box-shadow</code> aren’t part of the box, and therefore have no effect on the layout.</li>
</ul>
<style>
.meta-contextual-display {
display: none
}
html[data-user-agent*="Chrome"] .meta-contextual-display,
html[data-user-agent*="iPad"] .meta-contextual-display,
html[data-user-agent*="iPhone"] .meta-contextual-display,
html[data-user-agent*="iPod"] .meta-contextual-display {
display: block
}
</style>
<div class="meta meta-contextual-display">
<p>Quick note: most CSS properties in this textbook can be clicked to obtain contextual information. Try clicking <code>box-shadow</code>, for example.</p>
</div>
<h2>Box sizing</h2>
<p>The <code>box-sizing</code> property gives you a little control around how boxes are sized within this model. The two possible values for <code>box-sizing</code> are <code>content-box</code> and <code>border-box</code><sup><a href="#cite-2">[2]</a></sup>.</p>
<dl>
<dt><code>content-box</code></dt>
<dd><em>The default.</em> When computing the size of a box, padding and border are added.</dd>
<dt><code>border-box</code></dt>
<dd>When computing the size of a box, padding and border are folded in.</dd>
</dl>
<p>For example:</p>
<h3>Example</h3>
<p>Both of these boxes have the following CSS, but one has <code>box-sizing</code> <code>content-box</code> and the other <code>border-box</code>.</p>
<div class="example-wrapper">
<style>
.example-box-sizing .box {
height: 5em;
width: 5em;
padding: 1em;
border: .25em solid
}
</style>
<pre><code>.box {
height: 5em;
width: 5em;
padding: 1em;
border: .25em solid
}</code></pre>
<div class="example side-by-side example-box-sizing">
<div class="left">
<p><code>content-box</code></p>
<div class="example-content">
<div class="box" style="box-sizing: content-box; -moz-box-sizing: content-box"></div>
</div>
</div>
<div class="right">
<p><code>border-box</code></p>
<div class="example-content">
<div class="box" style="box-sizing: border-box; -moz-box-sizing: border-box"></div>
</div>
</div>
</div>
</div>
<p>In the <code>border-box</code> case, the width and height of the <code>.box</code> are <code>5em</code>, <em>exactly what we set</em>. In the <code>content-box</code> case, the width and height are <code>7.5em = 5 + (2 * 1) + (2 * .25)</code>, since we need to include the padding and border on both sides.</p>
<h3 class="magic">Flexible inputs</h3>
<p>One of the benefits of using <code>border-box</code> is you can set a <code>padding</code> and <code>width</code> of <em>mixed units</em> without creating strange sizing edge cases. One fantastic use for this is creating flexible inputs with a fixed padding size.</p>
<p>In the example below, our input has a specific padding in <code>em</code>s and yet we can still specify a width in <code>%</code> (<code>padding: .4em .55em</code> and <code>width: 100%</code>, respectively).</p>
<div class="example-wrapper">
<style>
.example-flexible-input .example-content {
background: #eee
}
.example-flexible-input .box {
background: #ccc;
width: 75%;
padding: 1em
}
.example-flexible-input .box-inner {
overflow: hidden
}
.example-flexible-input .box-inner p:first-child {
margin-top: 0
}
.example-flexible-input input[type="text"] {
box-sizing: border-box;
width: 100%;
padding: .4em .55em;
font-size: inherit;
font-family: inherit;
color: inherit;
border: 0;
border-radius: .25em;
outline: none
}
</style>
<pre><code>input[type="text"] {
/* Flexibility */
box-sizing: border-box;
width: 100%;
/* Styling */
padding: .4em .55em;
font-size: inherit;
font-family: inherit;
color: inherit;
border: 0;
border-radius: .25em;
outline: none
}</code></pre>
<div class="example example-flexible-input">
<div class="example-content">
<div class="box">
<div class="box-inner">
<p>Box</p>
<input type="text" placeholder="Text input">
</div>
</div>
</div>
<p>
<input type="range" class="example-flexible-input-slider" min="20" max="100" value="75">
<span> <code>width: <span class="example-flexible-input-slider-value">75%</span></code></span>
</p>
<p>Adjust the box width and observe the input sizes itself perfectly within the box while maintaining a fixed padding.</p>
</div>
</div>
<script>
(function(){
var handler, slider;
handler = function(e) {
var width = e.target.valueAsNumber + '%';
document.querySelector('.example-flexible-input-slider-value').innerHTML = width;
Array.prototype.slice.call(document.querySelectorAll('.example-flexible-input .box')).forEach(function(box){
box.style.width = width;
});
};
slider = document.querySelector('.example-flexible-input-slider');
slider.addEventListener('change', handler);
slider.addEventListener('input', handler);
})();
</script>
<h3>tl;dr</h3>
<p>If you want <code>height</code> and <code>width</code> to behave in the most intuitive way, <a href="http://www.paulirish.com/2012/box-sizing-border-box-ftw/">listen to Paul Irish</a><sup><a href="#cite-3">[3]</a></sup> and put this at the top of your CSS:</p>
<pre><code>html {
box-sizing: border-box
}
*, *::before, *::after {
box-sizing: inherit
}</code></pre>
<hr>
<h3>Further reading</h3>
<ul>
<li><a href="http://caniuse.com/css3-boxsizing">Can I Use: CSS3 Box-sizing?</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Boxes">MDN: Boxes</a></li>
</ul>
<h3>Citations</h3>
<ol>
<li><a id="cite-1" href="http://www.w3.org/TR/CSS2/box.html">w3: Box model</a></li>
<li><a id="cite-2" href="https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing">MDN: box-sizing</a> — There is also <code>padding-box</code>, but don’t worry about that.</li>
<li><a id="cite-3" href="http://www.paulirish.com/2012/box-sizing-border-box-ftw/">Paul Irish: * { Box-sizing: Border-box } FTW</a></li>
</ol>
<hr>
<nav class="chapter-navigation">
<a class="previous-chapter" href="../preface">
<span class="title preface-title">Preface</span>
</a>
<a class="next-chapter" href="../2-layout">
<span class="number">2</span>
<span class="title">Layout</span>
</a>
</nav>
</div>
</div>
<script src="../../js/footer.js"></script>
</body>
</html>
================================================
FILE: chapters/2-layout/index.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Layout — Chapter 2 — Magic of CSS — Adam Schwartz</title>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<link rel="icon" href="/magic-of-css/favicon.ico">
<link rel="stylesheet" href="../../css/base.css">
<link rel="stylesheet" href="../../css/logo.css">
<link rel="stylesheet" href="../../css/chapter.css">
<script src="../../js/chapters.js"></script>
</head>
<body>
<div class="page">
<a class="logo" href="/../.."><h1 class="the-magic-of">The Magic of CSS</h1><div class="css-rainbow"><div class="css-letter css-rainbow-c"><div class="rainbow"><div class="bands"><div class="red"></div><div class="orange"></div><div class="yellow"></div><div class="green"></div><div class="blue"></div><div class="purple"></div></div></div></div><div class="css-letter css-rainbow-s css-rainbow-s-1"><div class="top-half"><div class="rainbow"><div class="bands"><div class="red"></div><div class="orange"></div><div class="yellow"></div><div class="green"></div><div class="blue"></div><div class="purple"></div></div></div></div><div class="bottom-half"><div class="rainbow"><div class="bands"><div class="purple"></div><div class="blue"></div><div class="green"></div><div class="yellow"></div><div class="orange"></div><div class="red"></div></div></div></div></div><div class="css-letter css-rainbow-s css-rainbow-s-2"><div class="top-half"><div class="rainbow"><div class="bands"><div class="red"></div><div class="orange"></div><div class="yellow"></div><div class="green"></div><div class="blue"></div><div class="purple"></div></div></div></div><div class="bottom-half"><div class="rainbow"><div class="bands"><div class="purple"></div><div class="blue"></div><div class="green"></div><div class="yellow"></div><div class="orange"></div><div class="red"></div></div></div></div></div></div></a>
<div class="chapter">
<h1>
<span class="number">Chapter 2</span>
<span class="title">Layout</span>
</h1>
<p><em>In the <a href="../1-the-box">previous chapter</a>, we learned that each element in the page is a rectangular box. In this chapter, we will see how multiple boxes get laid out on a page.</em></p>
<hr>
<h2>Block, inline, and inline-block</h2>
<p>With respect to layout, the <code>display</code> property has three values you should be most concerned with. Here are the main differences between how these three display types get laid out:</p>
<dl>
<dt><code>block</code></dt>
<dd>My width is sized by my parent and I can have widths and heights set on me. My height is determined by my content.</dd>
<dt><code>inline</code></dt>
<dd>My width and height are determined by <em>my contents</em> and widths and heights don’t do anything to me. Think of me like a word flowing in a paragraph.</dd>
<dt><code>inline-block</code></dt>
<dd>I am the same as <code>block</code> except my width is determined by my contents.</dd>
</dl>
<h3>Example</h3>
<p>Below we have elements of each of these three display types with the following additional CSS applied to all of them:</p>
<div class="example-wrapper">
<style>
.example-display .example-content * {
background: #eee;
border: .125em solid;
margin-bottom: .5em;
padding: .5em
}
.example-display .example-content .block {
display: block
}
.example-display .example-content .inline {
display: inline
}
.example-display .example-content .inline-block {
display: inline-block
}
</style>
<pre><code>* {
background: #eee;
border: .125em solid;
margin-bottom: .5em;
padding: .5em
}</code></pre>
<div class="example example-display">
<div class="example-content">
<div class="block">Block</div>
<div class="block">Block</div>
<span class="inline">Inline</span>
<span class="inline">Inline</span>
<span class="inline">Inline</span>
<span class="inline">Inline</span>
<span class="inline">Inline</span>
<span class="inline">Inline</span>
<span class="inline">Inline</span>
<span class="inline">Inline</span>
<span class="inline">Inline</span>
<div class="block">Block</div>
<div class="block">Block</div>
<div class="inline-block">Inline block</div>
<div class="inline-block">Inline block</div>
<div class="inline-block">Inline block</div>
</div>
<p>
<label>
<input type="checkbox" class="example-display-fixed-width-checkbox"> Set all widths to 20%
</label>
</p>
</div>
<script>
document.querySelector('.example-display-fixed-width-checkbox').addEventListener('change', function(e){
var checked = e.target.checked;
Array.prototype.slice.call(document.querySelectorAll('.example-display .example-content *')).forEach(function(box){
box.style.width = checked ? '20%' : 'auto';
});
});
</script>
</div>
<p>One thing to note here is the difference between <code>inline</code> and <code>inline-block</code>. The <code>inline</code> elements display their <code>.5em</code> padding and <code>.125em</code> border, but only the lefts and rights (and not tops and bottoms) of these actually affect their layout. Whereas the <code>inline-block</code> elements reposition themselves in layout due to their padding and border, just as do the <code>block</code> elements.</p>
<p>Also note that when setting the width to <code>20%</code> on all elements, the <code>block</code> elements <em>still don’t wrap</em>. Assuming no floats are in the mix, <code>block</code> elements do not allow horizontal neighbors.</p>
<h3 class="magic">Horizontal scrolling with inline-block</h3>
<p>Horizontal scrolling sections can be tricky. Fortunately, this is a place where <code>inline-block</code> can help out.</p>
<p>Let’s say I want to display some code with a background color applied to each row of text on hover:</p>
<style>
.example-row-highlight-fail .row {
display: block
}
.example-row-highlight-fail .row:hover {
background: #ccc
}
</style>
<pre class="example-row-highlight-fail"><code><span class="row">body {</span><!--
--><span class="row"> background: red /* I know it’s weird to make the whole page red, but sometimes it’s just what you have to do.... */</span><!--
--><span class="row">}</span></code></pre>
<p>If you scroll to the right, you’ll see that the row hover color doesn’t extend all of the way to the right. This is because each row wrapper is a block element, sizing itself to the width of its parent, not to the scroll width of its parent.</p>
<p>By adding an <code>inline-block</code> element which wraps all of the rows, we get the scroll we want, and the row elements (still <code>display: block</code>) can fill the width of <em>that</em> element, which is the same as the scroll width of the whole code block, because it is sized by <em>its contents</em>—in this case, the longest row.</p>
<style>
.example-row-highlight-fix .inline-block {
display: inline-block
}
.example-row-highlight-fix .row {
display: block
}
.example-row-highlight-fix .row:hover {
background: #ccc
}
</style>
<pre class="example-row-highlight-fix"><code><span class="inline-block"><span class="row">body {</span><!--
--><span class="row"> background: red /* I know it’s weird to make the whole page red, but sometimes it’s just what you have to do.... */</span><!--
--><span class="row">}</span></span></code></pre>
<h2>HTML and body</h2>
<p>The <code>html</code> and <code>body</code> elements are rectangles, just like any other elements on the page. We’ll cover them more in depth in a later chapter—but for now, just know that they’re both <code>block</code> elements.</p>
<h2>Tables</h2>
<p>Tables are crazy, and <a href="../3-tables">Chapter 3</a> covers them in more detail. But with respect to layout, think of a <code>table</code> like an <code>inline-block</code> element with one special property: its <code>table-cell</code> children can center their contents vertically.</p>
<p>Aside from the relatively new and experimental <code>display</code> property <code>flex</code> (which may be covered in a later chapter), no other element can do this.</p>
<p>So with respect to layout, think of tables as a tool which can be used to center <em>arbitrary content</em> vertically.</p>
<h3 class="magic">Vertical centering content with unknown height</h3>
<p>Vertical center centering with a table couldn’t be simpler.</p>
<p>But if you’re using a table for this purpose (and not to display tabular-data), you should instead use another type of element (<code>div</code>, for example), and set its display property to <code>table</code> to mimick the table behavior.</p>
<div class="example-wrapper">
<style>
.example-vertical-centering .vertical-outer {
display: table;
width: 100%;
background: #eee;
height: 10em
}
.example-vertical-centering .vertical-inner {
display: table-cell;
padding: 0 4em;
text-align: center;
vertical-align: middle
}
</style>
<pre><code><style>
.vertical-outer {
display: table;
height: 10em
}
.vertical-inner {
display: table-cell;
vertical-align: middle
}
</style>
<div class="vertical-outer">
<div class="vertical-inner">
<p>I’m so centered it’s not even funny.</p>
</div>
</div></code></pre>
<div class="example example-vertical-centering">
<div class="example-content">
<div class="vertical-outer">
<div class="vertical-inner">
<p>I’m so centered it’s not even funny.</p>
</div>
</div>
</div>
</div>
</div>
<p><em>And that’s it!</em></p>
<p>As an aside, centering something vertically when you know its height is trivial. First position the element, then set a <code>top</code> and <code>bottom</code> to the same value (<code>0</code> works), set your desired <code>height</code>, and then set <code>margin-top</code> and <code>margin-bottom</code> to <code>auto</code>.</p>
<h2>Text align</h2>
<p>Basically, text-align lets you align text, child inline elements, and child inline block elements to the left, right, center, or justified. (You know what these mean if you’ve ever used a WYSIWYG editor.)</p>
<p>Now for some magic:</p>
<h3 class="magic">Grid with text-align justify</h3>
<p>Since <code>inline-block</code> elements are treated more or less as text, you can use <code>text-align: justify</code> on a list of <code>inline-block</code> elements to create a grid structure.</p>
<div class="example-wrapper">
<style>
.example-text-align-justify .grid {
border: .125rem solid;
text-align: justify;
font-size: 0;
padding: 4% 4% 0 4%
}
.example-text-align-justify .box {
font-size: 1rem;
display: inline-block;
background: #eee;
border: .125em solid;
width: 30%;
padding: 2%
}
.example-text-align-justify .box:nth-last-child(n+5) {
margin-bottom: 4%
}
.example-text-align-justify .break {
display: inline-block;
width: 30%;
height: 0
}
</style>
<pre><code><style>
.grid {
border: .125rem solid;
text-align: justify;
font-size: 0;
padding: 4% 4% 0 4%
}
.box {
font-size: 1rem;
display: inline-block;
background: #eee;
border: .125em solid;
width: 30%;
padding: 2%
}
/* All but the last 3 boxes */
.box:nth-last-child(n+5) {
margin-bottom: 4%
}
.break {
display: inline-block;
width: 30%;
height: 0
}
</style>
<div class="grid">
<div class="box">Column</div>
<div class="box">Column</div>
<div class="box">Column</div>
<div class="box">Column</div>
<div class="box">Column</div>
<div class="box">Column</div>
<div class="break"></div>
</div></code></pre>
<div class="example example-text-align-justify">
<div class="example-content">
<div class="grid">
<div class="box">Box</div>
<div class="box">Box</div>
<div class="box">Box</div>
<div class="box">Box</div>
<div class="box">Box</div>
<div class="box">Box</div>
<div class="break"></div>
</div>
</div>
<p>
<input type="range" class="example-text-align-justify-slider" min="26" max="30" value="30">
<span> <code>width: <span class="example-text-align-justify-slider-value">30%</span></code></span>
</p>
<p>Adjust the width of the boxes and note that <code>text-align: justify</code> keeps the grid intact.</p>
</div>
<script>
(function(){
var handler, slider;
handler = function(e) {
var width = e.target.valueAsNumber + '%';
document.querySelector('.example-text-align-justify-slider-value').innerHTML = width;
Array.prototype.slice.call(document.querySelectorAll('.example-text-align-justify .box')).forEach(function(box){
box.style.width = width;
});
};
slider = document.querySelector('.example-text-align-justify-slider');
slider.addEventListener('change', handler);
slider.addEventListener('input', handler);
})();
</script>
</div>
<h2>Floats</h2>
<p>Floats are crazy, so crazy that they’ll also get their own chapter.</p>
<p>But when it comes to positioning, basically what you need to know is that floated elements behave kind of like <code>inline-block</code> elements, regardless of what their <code>display</code> property value actually is.</p>
<p>The truth is, these days, since <code>inline-block</code> is supported pretty widely, there’s not as much use for <code>float</code> anymore. We’ll still cover it since it’s a card up your sleeve, and you should know how to whip it out. But don’t worry about it too much just yet.</p>
<p>In the meantime, you can read up on the <a href="http://www.w3.org/TR/CSS2/visuren.html#dis-pos-flo">relationship between display, position, and float</a> in the w3 CSS2 spec.<sup><a href="#cite-1">[1]</a></sup></p>
<h2>Positioning</h2>
<p>Ahh, this is where the real fun begins.</p>
<p>An element is said to be “positioned” if its <code>position</code> property is any value except <code>static</code>.</p>
<p>When an element is positioned, it is laid out according to whichever positioning properties <code>top</code>, <code>bottom</code>, <code>left</code>, and <code>right</code> it has set.</p>
<p>This means not only do these properties reposition (or move) elements, they also can resize elements. For example, with <code>position</code> <code>absolute</code> or <code>fixed</code>, you can set both a <code>top</code> and <code>bottom</code> to essentially impose a fixed height on the element. The precedence here can get pretty complicated, but as a general rule, if you set <code>top</code>, <code>bottom</code>, <em>and</em> <code>height</code> for a positioned element, the <code>height</code> value will be ignored.</p>
<p>The <code>position</code> property can take on the following values:</p>
<dl>
<dt><code>static</code></dt>
<dd><em>The default</em>. Any <code>top</code>, <code>right</code>, <code>bottom</code>, or <code>left</code> properties are ignored.</dd>
<dt><code>absolute</code></dt>
<dd>The element will be removed from its original layout position and positioned relative to its nearest positioned parent by the positioning properties.</dd>
<dt><code>fixed</code></dt>
<dd>The element will be removed from its original layout position and positioned relative to the window. (Mobile devices with zoom may have indeterminate behavior.)</dd>
<dt><code>relative</code></dt>
<dd>Unlike absolute or fixed, the element stays in its original layout position and the <code>top</code>, <code>right</code>, <code>bottom</code>, or <code>left</code> properties only <em>nudge</em> it from that original position.</dd>
</dl>
<p>This stuff can be confusing, so we’ll highlight some important takeaways from these descriptions:</p>
<ul>
<li><code>absolute</code> and <code>fixed</code> elements are not part of normal document layout. When their dimensions change, only their child elements are affected. (There is a subtle exception to this which is that <code>absolute</code> positioned elements can cause a scroll bar [in the positive content flow direction: by default, to the right or down] and this can affect the layout of other elements in the page.)</li>
<li><code>static</code> and <code>relative</code> elements are part of the layout. When their layout changes, so do their document neighbors.</li>
<li>When <em>nudged</em> via <code>top</code>, <code>right</code>, <code>bottom</code>, or <code>left</code>, <code>relative</code> elements do not affect their document neighbors. Instead, those neighbors act like the element was never <em>nudged</em> from its original position. (The scroll exception applies here as well.)</li>
<li>Confusingly, <code>relative</code> is not so-named because its child elements will be positioned “relative” to it. (That is simply a consequence of it being positioned at all, and so the same could be said about <code>absolute</code> and <code>fixed</code> elements as well.) Rather, it is so-named to describe how you can “relatively” <em>nudge</em> it based on its original position.</li>
</ul>
<p>Now again, for a little magic:</p>
<h3 class="magic">100% <code>top</code>, <code>bottom</code>, <code>left</code>, or <code>right</code></h3>
<p>Positioning a child element abbutted to the outside of its parent is a bit tricky.</p>
<p>The naive approach is to use a negative positioning property which matches its dimension.</p>
<p>For example:</p>
<div class="example-wrapper">
<style>
.example-position-negative .parent {
position: relative;
text-align: center;
padding: 1.25em;
background: #eee;
margin-top: 2.5em
}
.example-position-negative .child {
position: absolute;
height: 2.5em;
top: -2.5em;
right: 0;
line-height: 2.5em;
background: #444;
color: #fff;
padding: 0 .625em
}
</style>
<pre><code>.parent {
position: relative;
text-align: center;
padding: 1.25em;
background: #eee
}
.child {
position: absolute;
height: 2.5em;
top: -2.5em;
right: 0;
line-height: 2.5em;
background: #444;
color: #fff;
padding: 0 .625em
}</code></pre>
<div class="example example-position-negative">
<div class="example-content">
<div class="parent">
Parent
<div class="child">Child</div>
</div>
</div>
</div>
</div>
<p>Note the following two lines of CSS:</p>
<pre><code>height: 2.5em;
top: -2.5em;</code></pre>
<p>This part is unideal because it’s not <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a> and because we had to specify a height. <em>When possible, it’s better not to specify fixed values in CSS.</em> The more you can let things get sized by content the better, because it means your design is more flexible, supports more use-cases, and is less likely to create future bugs.</p>
<p>So what can we do instead? Use <code>100%</code> values.</p>
<p>Instead of thinking moving the child up by a negative <code>top</code>, think of it as moving <code>100%</code> from the bottom. Now our same example can be written like this instead:</p>
<div class="example-wrapper">
<style>
.example-position-100 .parent {
position: relative;
text-align: center;
padding: 1.25em;
background: #eee;
margin-top: 2.75em
}
.example-position-100 .child {
position: absolute;
bottom: 100%;
right: 0;
background: #444;
color: #fff;
padding: .625em
}
</style>
<pre><code>.parent {
position: relative;
text-align: center;
padding: 1.25em;
background: #eee
}
.child {
position: absolute;
bottom: 100%;
right: 0;
background: #444;
color: #fff;
padding: .625em
}</code></pre>
<div class="example example-position-100">
<div class="example-content">
<div class="parent">
Parent
<div class="child">Child</div>
</div>
</div>
</div>
</div>
<p>Notice how in this version we were able to simplify the padding and line-height because the child box is now sizing itself to its contents, rather than the other way around.</p>
<h2>Transforms</h2>
<p>These will definitely get their own chapter. Transforms are where a lot of the real magic lives. But for now, note that unfortunately <a href="http://meyerweb.com/eric/thoughts/2011/09/12/un-fixing-fixed-elements-with-css-transforms/">transformed elements are treated as positioned even if they are statically-positioned</a><sup><a href="#cite-2">[2]</a></sup>. Commit this to memory or at some point it will probably burn you.</p>
<hr>
<h3>Further reading</h3>
<ul>
<li><a href="http://quirksmode.org/css/css2/display.html">Quirksmode: display</a> — has a great toy for playing with the different property values.</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Layout">MDN: Layout</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/position">MDN: position</a></li>
</ul>
<h3>Citations</h3>
<ol>
<li><a id="cite-1" href="http://www.w3.org/TR/CSS2/visuren.html#dis-pos-flo">Relationships between display, position, and float</a></li>
<li><a id="cite-2" href="http://meyerweb.com/eric/thoughts/2011/09/12/un-fixing-fixed-elements-with-css-transforms/">Un-fixing Fixed Elements with CSS Transforms</a></li>
</ol>
<hr>
<nav class="chapter-navigation">
<a class="previous-chapter" href="../1-the-box">
<span class="number">1</span>
<span class="title">The Box</span>
</a>
<a class="next-chapter" href="../3-tables">
<span class="number">3</span>
<span class="title">Tables</span>
</a>
</nav>
</div>
</div>
<script src="../../js/footer.js"></script>
</body>
</html>
================================================
FILE: chapters/3-tables/index.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Tables — Chapter 3 — Magic of CSS — Adam Schwartz</title>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<link rel="icon" href="/magic-of-css/favicon.ico">
<link rel="stylesheet" href="../../css/base.css">
<link rel="stylesheet" href="../../css/logo.css">
<link rel="stylesheet" href="../../css/chapter.css">
<script src="../../js/chapters.js"></script>
</head>
<body>
<div class="page">
<a class="logo" href="/../.."><h1 class="the-magic-of">The Magic of CSS</h1><div class="css-rainbow"><div class="css-letter css-rainbow-c"><div class="rainbow"><div class="bands"><div class="red"></div><div class="orange"></div><div class="yellow"></div><div class="green"></div><div class="blue"></div><div class="purple"></div></div></div></div><div class="css-letter css-rainbow-s css-rainbow-s-1"><div class="top-half"><div class="rainbow"><div class="bands"><div class="red"></div><div class="orange"></div><div class="yellow"></div><div class="green"></div><div class="blue"></div><div class="purple"></div></div></div></div><div class="bottom-half"><div class="rainbow"><div class="bands"><div class="purple"></div><div class="blue"></div><div class="green"></div><div class="yellow"></div><div class="orange"></div><div class="red"></div></div></div></div></div><div class="css-letter css-rainbow-s css-rainbow-s-2"><div class="top-half"><div class="rainbow"><div class="bands"><div class="red"></div><div class="orange"></div><div class="yellow"></div><div class="green"></div><div class="blue"></div><div class="purple"></div></div></div></div><div class="bottom-half"><div class="rainbow"><div class="bands"><div class="purple"></div><div class="blue"></div><div class="green"></div><div class="yellow"></div><div class="orange"></div><div class="red"></div></div></div></div></div></div></a>
<div class="chapter">
<h1>
<span class="number">Chapter 3</span>
<span class="title">Tables</span>
</h1>
<h2><code>table-layout</code></h2>
<p>In the <a href="../2-layout">previous chapter</a> we discussed layout. But what we meant by that is the construction of your content from a design perspective—how you structure your app geometrically to make sense for your use case. Think the <a href="../../potions/two-pane-app/">Two Pane App</a> potion.</p>
<p>But <code>layout</code> has a specific meaning in various contexts. In the context of tables, it means how the browser decides to size columns and rows of a <code>table</code> element based on the CSS applied by the user agent and you, and the content within each table cell.</p>
<p>This process is truly <em>magical</em>.</p>
<p>A complex layout algorithm is used for both the <a href="http://www.w3.org/TR/CSS21/tables.html#width-layout">horizontal</a> and <a href="http://www.w3.org/TR/CSS21/tables.html#height-layout">vertical</a>. And these algorithms fork early based on the <code>table-layout</code> you specify, of which there are two options:</p>
<dl>
<dt><code>auto</code></dt>
<dd><em>The default</em>. I attempt to size columns relatively to each other by the widest cell in each column, unless you give me specific widths, at which point I use the widths you specify to make relative comparisons. (<a href="http://www.w3.org/TR/CSS21/tables.html#auto-table-layout">CSS spec</a>)</dd>
<dt><code>fixed</code></dt>
<dd>I attempt to size columns evenly, unless you give me specific widths in <code>px</code>, at which point I attempt to honor your sizing exactly, unless I can’t because your math doesn’t work out. (<a href="http://www.w3.org/TR/CSS21/tables.html#fixed-table-layout">CSS spec</a>)</dd>
</dl>
<p>These are very rough definitions, and definitely not complete. I highly recommend you <a href="http://www.w3.org/TR/CSS21/tables.html">read through the spec</a> at some point to get a better understanding. But nothing is better than playing with live code, so let’s look at some examples to get a clearer picture.</p>
<h3>Example 1: No widths</h3>
<style>
.example-table-layout table {
background: transparent;
border-spacing: 0;
border-collapse: collapse;
width: 100%;
margin-bottom: 1em
}
.example-table-layout table td {
border: .125em solid #ccc
}
.example-table-layout p {
margin-top: 0
}
.example-table-layout a {
text-shadow: none
}
</style>
<div class="example example-table-layout">
<div class="example-content">
<p><code>table-layout: auto</code></p>
<table>
<tbody>
<tr>
<td>This is the title of some object</td>
<td><a href="javascript:;">Action</a></td>
</tr>
<tr>
<td>This is the title of another object</td>
<td><a href="javascript:;">Action</a></td>
</tr>
</tbody>
</table>
<p><code>table-layout: fixed</code></p>
<table style="table-layout: fixed">
<tbody>
<tr>
<td>This is the title of some object</td>
<td><a href="javascript:;">Action</a></td>
</tr>
<tr>
<td>This is the title of another object</td>
<td><a href="javascript:;">Action</a></td>
</tr>
</tbody>
</table>
</div>
</div>
<p>Notice how in the <code>fixed</code> case, the columns are sized evenly since no widths are specified, but in the <code>auto</code> cased they’re sized proportionally by the width of the cell contents.</p>
<h3>Example 2: Percentage widths</h3>
<p>Now let’s look at the same example with column widths set to <code>20%</code> and <code>50%</code>, respectively.</p>
<style>
.example-table-layout-sized-percent table tr td:nth-child(1) {
width: 20%
}
.example-table-layout-sized-percent table tr td:nth-child(2) {
width: 50%
}
</style>
<div class="example example-table-layout example-table-layout-sized-percent">
<div class="example-content">
<p><code>table-layout: auto</code></p>
<table>
<tbody>
<tr>
<td>This is the title of some object</td>
<td><a href="javascript:;">Action</a></td>
</tr>
<tr>
<td>This is the title of another object</td>
<td><a href="javascript:;">Action</a></td>
</tr>
</tbody>
</table>
<p><code>table-layout: fixed</code></p>
<table style="table-layout: fixed">
<tbody>
<tr>
<td>This is the title of some object</td>
<td><a href="javascript:;">Action</a></td>
</tr>
<tr>
<td>This is the title of another object</td>
<td><a href="javascript:;">Action</a></td>
</tr>
</tbody>
</table>
</div>
</div>
<p>
<label>
<input type="checkbox" class="example-table-layout-white-space-nowrap-checkbox"> Toggle <code>white-space: nowrap</code>
</label>
</p>
<script>
document.querySelector('.example-table-layout-white-space-nowrap-checkbox').addEventListener('change', function(e){
var checked = e.target.checked;
Array.prototype.slice.call(document.querySelectorAll('.example-table-layout-sized-percent td')).forEach(function(cell){
cell.style.whiteSpace = checked ? 'nowrap' : 'normal';
});
});
</script>
<p><strong>In both cases</strong>, our widths are being taken into account, but only relatively. This is always true with <code>auto</code> but it’s additionally true here with <code>fixed</code> because the widths are specified in percentages. The browser says, “20% is 2/7ths out of the total 20+50%”, so when the table is <code>1000px</code> wide, the first column ends up at <code>284px</code> and the second column at <code>714px</code>, roughly a ratio of <code>2:5</code>. (It won’t be perfectly 2:5 due to <code>cell-spacing</code>, <code>cell-padding</code>, <code>border</code>, <code>border-spacing</code>, <code>border-collapse</code>, etc., rounding, and other constraints.)</p>
<p>Notice that with <code>white-space: nowrap</code> applied to each cell, the auto case compensates but the fixed case lets the text overflow.</p>
<p>Challenge question to think about: <em>why is first column slightly wider in the <code>fixed</code> case?</em></p>
<h3>Example 3: Mixed unit widths</h3>
<p>Now let’s look at the same example with column widths set to <code>400px</code> and <code>70%</code>, respectively.</p>
<style>
.example-table-layout-sized table tr td:nth-child(1) {
width: 400px
}
.example-table-layout-sized table tr td:nth-child(2) {
width: 70%
}
</style>
<div class="example example-table-layout example-table-layout-sized">
<div class="example-content">
<p><code>table-layout: auto</code></p>
<table>
<tbody>
<tr>
<td>This is the title of some object</td>
<td><a href="javascript:;">Action</a></td>
</tr>
<tr>
<td>This is the title of another object</td>
<td><a href="javascript:;">Action</a></td>
</tr>
</tbody>
</table>
<p><code>table-layout: fixed</code></p>
<table style="table-layout: fixed">
<tbody>
<tr>
<td>This is the title of some object</td>
<td><a href="javascript:;">Action</a></td>
</tr>
<tr>
<td>This is the title of another object</td>
<td><a href="javascript:;">Action</a></td>
</tr>
</tbody>
</table>
</div>
</div>
<p><em>Ok...</em>. Since the width of each table is <code><span class="example-table-layout-sized-table-widths"></span>px</code>, there’s no way for the browser to fit the columns <code>400px</code> and <code>70% × <span class="example-table-layout-sized-table-widths"></span>px</code> into a <code><span class="example-table-layout-sized-table-widths"></span>px</code>–wide table. So it does the best it can.</p>
<p><strong>In the <code>auto</code> case</strong>, our widths are being taken into account, but only relatively. It compares <code>400px / <span class="example-table-layout-sized-table-widths"></span>px</code> to <code>70% × <span class="example-table-layout-sized-table-widths"></span>px</code> and does the best it can. (The behavior here varies from browser to browser.)</p>
<p><strong>In the <code>fixed</code> case</strong>, the <code>400px</code> is honored, since fixed values are prioritized over percentage based values, and so the second column gets the remainder.</p>
<script>
Array.prototype.slice.call(document.querySelectorAll('.example-table-layout-sized-table-widths')).forEach(function(item){
item.innerHTML = document.querySelector('.example-table-layout-sized').clientWidth;
});
</script>
<h2>Tabular data</h2>
<p>This is a CSS course, so I won’t spend much time here. But the main reason to use tables in an application is to display <em>tabular data</em>. Tabular data means anything you might display in a spreadsheet. A content matrix.</p>
<p>When it comes to styling tables with tabular data, there are some good general rules to follow:</p>
<ul>
<li>Wide tables should be tiger-striped or use a <code>:hover</code> background color (or similar) to help the eye associate cells-of-the-same-row.</li>
<li>Columns of numerical data should be right aligned so that the digits line up.</li>
<li>Right-most columns may need to be right aligned to avoid a ragged right edge (think <code>text-align: justify</code>).</li>
<li>When possible, row heights should be identical to make vertical scanning easier. (This general principle is known in the biz as “vertical rhythm”, and it’s <a href="https://www.google.com/search?q=vertical+rhythm+css">very important</a>.)</li>
</ul>
<p>Check out the <a href="../../potions/table-styling/">table styling potion</a> for an example table design which follows these rules.
<h2>Tables as a layout tool</h2>
<p>In the <a href="../2-layout">previous chapter on layout</a>, we showed that tables can be used to center vertically content of arbitrary height. Until <code>flex</code> is widely supported, you should feel comfortable using tables for this. But other than that, if you catch yourself using a <code>table</code> to implement layout constructs that don’t have to do with tabular data, <em>you’re probably doing it wrong</em>.</p>
<p>If your <a href="http://caniuse.com/flexbox">browser support is IE10+</a>, then use <code>flex</code><sup><a href="#cite-1">[1]</a></sup>. Phillip Walton has a <a href="http://philipwalton.github.io/solved-by-flexbox/demos/vertical-centering/">great tutorial</a><sup><a href="#cite-2">[2]</a></sup> on vertical centering with flexbox.</p>
<h2>Table gotchas</h2>
<p>There are <em><a href="http://www.hotdesign.com/seybold/everything.html">sooo</a></em><sup><a href="#cite-3">[3]</a></sup> <a href="http://coding.smashingmagazine.com/2009/04/08/from-table-hell-to-div-hell/">many</a><sup><a href="#cite-4">[4]</a></sup> <a href="http://www.vanseodesign.com/css/tables/">reasons</a><sup><a href="#cite-5">[5]</a></sup> why you shouldn’t use tables for anything other than tabular data or vertical centering (as discussed). But to drive that point home, here are some extremely common <em>gotchas</em> that make tables frustrating to work with.</p>
<h3>Gotcha 1: Table cells do not respect overflows (<code>table-layout: auto</code>, Firefox, IE)</h3>
<p>This means that even if you use <code>table-layout: fixed</code> and specify a pixel width, <code>overflow: hidden</code> isn’t going to actually work on a table cell in every browser. (If you use <code>table-layout: auto</code>, overflows won’t be respected in any browser.)</p>
<style>
.example-table-gotcha-1 table tr td:nth-child(1) {
width: 100px;
height: 20px;
overflow: hidden
}
</style>
<div class="example example-table-layout example-table-gotcha-1">
<div class="example-content">
<p><code>table-layout: auto</code></p>
<table>
<tbody>
<tr>
<td>I’m being told to be <code>100px</code> wide and <code>20px</code> tall, but I ain’t listening.</td>
<td>I’m just some text</td>
</tr>
</tbody>
</table>
</div>
</div>
<h3>Gotcha 2: Table cells don’t respect relative positioning (Firefox)</h3>
<p>Yup. You heard me correctly. You go apply <code>position: relative</code> to a table cell, place a <code>position: absolute</code> element inside, and in Firefox, the absolute element will be positioned relative to the earliest positioned parent of the table instead. Bummer.</p>
<p><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=35168">The bug</a> was reported in 2000.<sup><a href="#cite-6">[6]</a></sup></p>
<style>
.example-table-gotcha-2 table {
table-layout: fixed;
margin-bottom: 50px
}
.example-table-gotcha-2 table tr td {
position: relative
}
.example-table-gotcha-2 table tr td .box {
border: 2px solid #ff4136;
position: absolute;
right: 40px
}
</style>
<div class="example example-table-layout example-table-gotcha-2">
<div class="example-content">
<table>
<tbody>
<tr>
<td><div class="box">I am <code>position: absolute</code> with <code>right: 40px</code></div></td>
<td>I’m just some text</td>
</tr>
</tbody>
</table>
</div>
</div>
<h3>Gotchas tl;dr</h3>
<p>If, after evaluating the options, you believe that using a <code>table</code> element is the right way to go, just make sure you wrap the contents of every table cell with a <code>div</code>. This way you have all of the styling control you need for each cell while still being able to utilize the extremely powerful—albeit confusing—table layout engine.</p>
<hr>
<h3>Further reading</h3>
<ul>
<li><a href="http://www.w3.org/TR/CSS21/tables.html">w3: CSS2 Tables specification</a></li>
<li><a href="http://drewish.com/tools/vertical-rhythm/">Drewish: Vertical rhythm tool</a></li>
</ul>
<h3>Citations</h3>
<ol>
<li><a id="cite-1" href="http://caniuse.com/flexbox">Can I use: flex</a></li>
<li><a id="cite-2" href="http://philipwalton.github.io/solved-by-flexbox/demos/vertical-centering/">Solved by Flexbox: Vertical Centering</a></li>
<li><a id="cite-3" href="http://www.hotdesign.com/seybold/everything.html">Seybold Seminars: Why tables for layout is stupid</a></li>
<li><a id="cite-4" href="http://coding.smashingmagazine.com/2009/04/08/from-table-hell-to-div-hell/">Smashing Magazine: Table Layouts vs. Div Layouts: From Hell to… Hell?</a></li>
<li><a id="cite-5" href="http://www.vanseodesign.com/css/tables/">Vaneso Design: Are CSS Tables Better Than HTML Tables?</a></li>
<li><a id="cite-6" href="https://bugzilla.mozilla.org/show_bug.cgi?id=35168">Mozilla Bugzilla: relative positioning of table cells doesn’t work</a></li>
</ol>
<hr>
<nav class="chapter-navigation">
<a class="previous-chapter" href="../2-layout">
<span class="number">2</span>
<span class="title">Layout</span>
</a>
<a class="next-chapter" href="../4-color">
<span class="number">4</span>
<span class="title">Color</span>
</a>
</nav>
</div>
</div>
<script src="../../js/footer.js"></script>
</body>
</html>
================================================
FILE: chapters/4-color/index.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Color — Chapter 4 — Magic of CSS — Adam Schwartz</title>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<link rel="icon" href="/magic-of-css/favicon.ico">
<link rel="stylesheet" href="../../css/base.css">
<link rel="stylesheet" href="../../css/logo.css">
<link rel="stylesheet" href="../../css/chapter.css">
<script src="../../js/chapters.js"></script>
</head>
<body>
<div class="page">
<a class="logo" href="/../.."><h1 class="the-magic-of">The Magic of CSS</h1><div class="css-rainbow"><div class="css-letter css-rainbow-c"><div class="rainbow"><div class="bands"><div class="red"></div><div class="orange"></div><div class="yellow"></div><div class="green"></div><div class="blue"></div><div class="purple"></div></div></div></div><div class="css-letter css-rainbow-s css-rainbow-s-1"><div class="top-half"><div class="rainbow"><div class="bands"><div class="red"></div><div class="orange"></div><div class="yellow"></div><div class="green"></div><div class="blue"></div><div class="purple"></div></div></div></div><div class="bottom-half"><div class="rainbow"><div class="bands"><div class="purple"></div><div class="blue"></div><div class="green"></div><div class="yellow"></div><div class="orange"></div><div class="red"></div></div></div></div></div><div class="css-letter css-rainbow-s css-rainbow-s-2"><div class="top-half"><div class="rainbow"><div class="bands"><div class="red"></div><div class="orange"></div><div class="yellow"></div><div class="green"></div><div class="blue"></div><div class="purple"></div></div></div></div><div class="bottom-half"><div class="rainbow"><div class="bands"><div class="purple"></div><div class="blue"></div><div class="green"></div><div class="yellow"></div><div class="orange"></div><div class="red"></div></div></div></div></div></div></a>
<div class="chapter">
<h1>
<span class="number">Chapter 4</span>
<span class="title">Color</span>
</h1>
<p><em>I know what you’re thinking. <em>A whole chapter on colors?</em> Trust me, one chapter is hardly enough. Color is an entire dimension, and it’s incredibly powerful.</em></p>
<hr>
<style>
figure.all-rgb {
width: 64rem;
max-width: 100%;
}
</style>
<figure class="cushy all-rgb">
<img src="images/all-rgb.png">
<figcaption>
<div class="figcaption">
All RGB colors<sup><a href="#cite-1">[1]</a></sup>
</div>
</figcaption>
</figure>
<style>
@media (max-width: 400px) {
.magic-color {
font-size: 12px;
}
}
</style>
<div class="magic-color red-gradient">
<h2>Challenges</h2>
</div>
<h2>A color is a color <em>isn’t a color</em>...</h2>
<h3>...not to computers</h3>
<p>The first myth worth dispelling is that colors are the same everywhere. In fact, the opposite is probably closer to the truth.</p>
<ul>
<li><a href="http://stackoverflow.com/questions/6237455/chrome-renders-colours-differently-from-safari-and-firefox">Colors render differently in different browsers.</a><sup><a href="#cite-2">[2]</a></sup></li>
<li><a href="https://discussions.apple.com/thread/1976783?tstart=0">Screenshots don’t always capture the same colors.</a><sup><a href="#cite-3">[3]</a></sup></li>
<li>Browsers have all sorts of bugs related to color rendering. (<a href="https://code.google.com/p/chromium/issues/detail?id=67230">Example</a><sup><a href="#cite-4">[4]</a></sup>)</li>
</ul>
<h3>...and not to the human eye</h3>
<p>The way a color appears to the human eye is dependent on many other factors as well, including:</p>
<ul>
<li>Type of device (laptop, desktop, mobile phone)</li>
<li>Distance and angle from the eye</li>
<li>Quality of display (number of colors it can render, accuracy of reproduction, supported viewing angle, maximum contrast, etc.)</li>
<li>Lighting conditions (inside vs. outside, day vs. night, near a window or not, etc.)</li>
<li>Vision of viewer (corrective lenses, visual impairments, colorblindness)</li>
</ul>
<p>As designers, we need to be aware of these challenges so we can address them. Here are just a few techniques to help:</p>
<ul>
<li>Choosing colors appropriate for type (and backgrounds of type)</li>
<li>Using skeuomorphism when appropriate to help people recognize objects as they would in the real world</li>
<li>Using contrast to increase readability (nobody can read white on beige)</li>
<li>Using patterns as a fallback for colorblind users when necessary (<a href="http://littlebigdetails.com/post/35775193711/trello-color-blind-friendly-mode-makes">Trello example</a><sup><a href="#cite-5">[5]</a></sup>)</li>
</ul>
<p>But remember, <a href="http://www.npr.org/2013/01/18/169708761/edward-tufte-wants-you-to-see-better">nothing is better than <em>seeing</em></a><sup><a href="#cite-6">[6]</a></sup>. Use your eyes (and the eyes of users you test). Test your color choices on a variety of devices and in a variety of lighting conditions until you feel confident that every user will see something desirable.</p>
<div class="magic-color green-gradient">
<h2>Opportunities</h2>
</div>
<h2>Color strategy</h2>
<p>As noted above, color is an extremely powerful tool. But with great power comes great responsibility. ;) Colors can be used in so many different ways, but using color for one thing may limit your ability to use it for something else. For example, using a particular green to represent your brand may limit your ability to use that same green to indicate “go”.</p>
<p>A color’s power as an aesthetic tool at least matches its power as a functional one. There may be times when you need to make a trade-off between using a color for one versus the other.</p>
<h2>Color tools</h2>
<h3>Sentiment</h3>
<p>Did you know <code>red</code><code class="color"><span style="background: red"></span></code> actually makes people hungry?<sup><a href="#cite-7">[7]</a></sup></p>
<p>Well, similarly it should be no surprise that colors can affect a person’s mood and opinion in a variety of ways. These effects are subjective and rely heavily on cultural and contextual cues. But they’re very real, so understanding them is crucial.</p>
<p>Do you want to shock people? Do you want to put them at ease? Do you want people to trust you? Do you want them to be excited? Do you want to motivate people to take action? Answering these questions will help you decide on colors for your app.</p>
<h3>Branding</h3>
<p>Colors are so powerful that a single color can suggest a brand.</p>
<p>Can you guess the brand for each of these colors? (Hover to see the answer.)</p>
<style>
.branding-color {
border-radius: .1875em;
margin-bottom: .25rem;
display: inline-block
}
.branding-color h2 {
padding: 0 1em;
display: inline-block;
text-align: center;
color: #fff;
font-weight: normal;
opacity: 0;
transition: opacity .3s;
cursor: default;
font-size: 1.2em;
margin: 1em 0;
line-height: .8em
}
.branding-color:hover h2 {
opacity: 1
}
</style>
<div class="branding-color" style="background: #3b5998">
<h2>Facebook</h2>
</div>
<div class="branding-color" style="background: #55acee">
<h2>Twitter</h2>
</div>
<div class="branding-color" style="background: #ed1c16">
<h2>Coca-Cola</h2>
</div>
<h3>Status</h3>
<p><a href="http://getbootstrap.com">Bootstrap</a><sup><a href="#cite-8">[8]</a></sup> has popularized the use of <a href="http://getbootstrap.com/css/#helper-classes">status classes</a><sup><a href="#cite-9">[9]</a></sup> which map to certain colors.</p>
<p>Many different apps use this or a similar mapping:</p>
<ul>
<li><code>#428bca</code><code class="color"><span style="background: #428bca"></span></code> = <code>primary</code></li>
<li><code>#dff0d8</code><code class="color"><span style="background: #dff0d8"></span></code> = <code>success</code></li>
<li><code>#d9edf7</code><code class="color"><span style="background: #d9edf7"></span></code> = <code>info</code></li>
<li><code>#fcf8e3</code><code class="color"><span style="background: #fcf8e3"></span></code> = <code>warning</code></li>
<li><code>#f2dede</code><code class="color"><span style="background: #f2dede"></span></code> = <code>danger</code></li>
</ul>
<p>By consistently using <code>#dff0d8</code><code class="color"><span style="background: #dff0d8"></span></code> to indicate success or <code>#f2dede</code><code class="color"><span style="background: #f2dede"></span></code> to indicate danger, you reinforce a pattern, making it easier for people to understand these concepts in the future.</p>
<h3>Motion, Attention</h3>
<p>Sometimes you want to grab a users’ attention. Transitioning a background color or text color (or simply changing it immediately) can be a great way to do so.</p>
<h3>Just about anything</h3>
<p>By no means is this meant to be an exhaustive list of the ways in which color can be used as a tool. <em>Use your creativity</em>, and try to think of ways color can be used to <em>reduce the complexity</em> of an existing UI.</p>
<p>Just make sure you don’t go overboard and use too many colors. Using too many colors can cause visual dissonance which makes it hard for a user to focus. When choosing a color scheme, it’s very important to think of how colors relate to one another to avoid such issues.</p>
<h2>Color schemes</h2>
<p>Picking a color scheme is essential. Some colors go well together and some don’t. There are a number of methodologies out there for picking colors. But the best advice is to use your eyes.</p>
<p>Color schemes can have as few as one non-grayscale color or as many as you want. But I’d caution against using more than three. In the biz, three colors which go well together are known as triads. Here are some great resources on color schemes:</p>
<ul>
<li><a href="http://tympanus.net/codrops/2012/09/17/build-a-color-scheme-the-fundamentals">Codrops: Build a Color Scheme: The Fundamentals</a> — A great overview on the different types of color combinations (monochromatic, complementary, triadic, tetradic, analogous)<sup><a href="#cite-10">[10]</a></sup></li>
<li><a href="http://colorschemedesigner.com">Color Scheme Designer</a> — A great tool for building color schemes with these types of color combinations<sup><a href="#cite-11">[11]</a></sup></li>
<li><a href="https://kuler.adobe.com/create/color-wheel">Adobe Kuler: Color Wheel</a> — Another great color scheme chooser<sup><a href="#cite-12">[12]</a></sup></li>
</ul>
<h2>Which color did you mean?</h2>
<p>One common color mistake I see frontend developers make is using a gray (e.g. <code>#ccc</code><code class="color"><span style="background: #ccc"></span></code>) when they <em>mean to use</em> black with an alpha (e.g. <code>rgba(0, 0, 0, 0.2)</code><code class="color"><span style="background: rgba(0, 0, 0, 0.2)"></span></code>).</p>
<p><em>But, they look the same!?</em>, you may protest. Well, sure. But only when they’re on white!</p>
<h3>Example</h3>
<p>Each of the white boxes below has <code>box-shadow: 0 .125em .5em [color]</code> applied with the color from the respective column.</p>
<style>
.example-which-color {
position: relative;
}
.example-which-color .container {
font-size: 0;
padding: 1.25rem;
line-height: normal;
background: #eee;
text-align: center
}
.example-which-color .container-green {
background: #85ddba
}
.example-which-color .item {
font-size: 1rem;
display: inline-block;
margin: 0 auto;
width: 30%;
min-width: 4em;
height: 4em;
background: #fff;
border-radius: .1875em
}
.example-which-color .item-grey-shadow {
box-shadow: 0 .125em .5em #ccc
}
.example-which-color .item-black-alpha-shadow {
box-shadow: 0 .125em .5em rgba(0, 0, 0, .2)
}
@media (max-width: 420px) {
.example-which-color > div > p:first-child {
position: absolute;
}
.example-which-color .left > p:first-child {
left: 0;
}
.example-which-color .right > p:first-child {
right: 0;
}
.example-which-color > div > .example-content {
margin-top: 2.5em;
}
}
</style>
<div class="example side-by-side example-which-color">
<div class="left">
<p><code>#ccc</code><code class="color"><span style="background: #ccc"></span></code></p>
<div class="example-content">
<div class="container">
<div class="item item-grey-shadow"></div>
</div>
<div class="container container-green">
<div class="item item-grey-shadow"></div>
</div>
</div>
</div>
<div class="right">
<p><code>rgba(0, 0, 0, 0.2)</code><code class="color"><span style="background: rgba(0, 0, 0, 0.2)"></span></code></p>
<div class="example-content">
<div class="container">
<div class="item item-black-alpha-shadow"></div>
</div>
<div class="container container-green">
<div class="item item-black-alpha-shadow"></div>
</div>
</div>
</div>
</div>
<p>Both boxes in the first row look fine. But notice how the bottom left white box looks strange. Its <code>#ccc</code><code class="color"><span style="background: #ccc"></span></code> shadow causes visual dissonance with the <code>#85ddba</code><code class="color"><span style="background: #85ddba"></span></code> background. Definitely not desired.</p>
<h2>Selecting a good default text color</h2>
<p>The browser default text color is <code>#000</code><code class="color"><span style="background: #000"></span></code>. I think this feels pretty intuitive to most people. Subconsciously, one’s head does something like this: <em>Ink is black. Documents are printed in ink. The web is a set of digital documents. So digital text should be black.</em></p>
<p>This is totally reasonable, and many great sites are designed with black. But an alternative to this which is better in many situations is to use a gray (e.g. <code>#333</code><code class="color"><span style="background: #333"></span></code>). This has several advantages.</p>
<ul>
<li>The sharp contrast of <span style="color: #000">black on white</span> can create visual artifacts or increase eye strain. (The opposite is also true. This is fairly subjective, but still worth noting.)</li>
<li>You get to “save” <code>#000</code><code class="color"><span style="background: #000"></span></code> for emphasis or accents. (This is perhaps the better reason.)</li>
</ul>
<p>You may be thinking: <em>but you just showed an example where you suggested using black with alpha over gray in situations where the background color may change... so why not set the default text color to <em><code>rgba(0, 0, 0, 0.8)</code><code class="color"><span style="background: rgba(0, 0, 0, 0.8)"></span></code></em> instead?</em></p>
<p>You’d be right, and that’s definitely an option. The main advantage this has is that text on non-white backgrounds will not get any grey+color clashing (as seen in the example above with the white box on the green background). But I wouldn’t recommend it universally for two reasons:</p>
<ol>
<li>
<p>When setting a <code>color</code> with an alpha between <code>0</code>and <code>1</code>, the WebKit browser default of <code>-webkit-font-smoothing: <wbr/>subpixel-antialiased</code> will no longer be honored, and you will never get subpixel antialiasing. (It will be as if you’d set that text to <code>-webkit-font-smoothing: <wbr/>antialiased</code> yourself.)</p>
<p>Which <code>font-smoothing</code> is “better” is contextual and fairly subjective. But it definitely feels like subpixel antialiasing is a bandage on a larger problem since: 1) WebKit on retina Macs don’t use subpixel antialiasing (and so it is likely that future high-resolution displays won’t as well), and 2) The popular blogging platform Medium.com (<a href="http://fontsinuse.com/uses/2575/medium">noted for its beautiful typography</a><sup><a href="#cite-13">[13]</a></sup>) applies <code>-webkit-font-smoothing: <wbr/>antialiased</code> on the entire document.</p>
</li>
<li>Performance may be slightly impacted. Remember, you’re now asking the browser to composite the text with whatever was behind it. This may be highly optimized in WebKit, but I wouldn’t count on that anywhere else.</li>
</ol>
<h2>tl;dr</h2>
<p>Color is powerful. Pick a good set of colors and stick to it! Really <em>see</em>. If something looks odd, it probably is.</p>
<hr>
<h3>A few sites with bold use of color</h3>
<ul>
<li><a href="http://www.hugeinc.com">HUGE Design</a></li>
<li><a href="http://doabackflip.com">Do a Back Flip Design</a></li>
<li><a href="http://www.mixd.co.uk">Mixd Design</a></li>
<li><a href="http://andrevv.com">Andrew McCarthy</a></li>
</ul>
<h3>Further reading</h3>
<ul>
<li><a href="http://www.w3.org/TR/css3-color/">w3: CSS Color Module Level 3</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/color">MDN: CSS Color</a></li>
<li><a href="http://tympanus.net/codrops/2011/08/03/minimal-contrasty-color-schemes/">Codrops: Minimal and Contrasty Color Schemes in Web Design</a></li>
</ul>
<h3>Citations</h3>
<ol>
<li><a id="cite-1" href="http://joco.name/2014/03/02/all-rgb-colors-in-one-image">Joco: All RGB colors in one image</a></li>
<li><a id="cite-2" href="http://stackoverflow.com/questions/6237455/chrome-renders-colours-differently-from-safari-and-firefox">StackOverflow: Chrome renders colours differently from Safari and Firefox</a></li>
<li><a id="cite-3" href="https://discussions.apple.com/thread/1976783?tstart=0">Apple Support Communities: Why is a Screenshot a different color when dropped back in to iWeb in Safari</a></li>
<li><a id="cite-4" href="https://code.google.com/p/chromium/issues/detail?id=67230">Chromium Issues: Inaccurate color profile rendering in Chrome for Mac</a></li>
<li><a id="cite-5" href="http://littlebigdetails.com/post/35775193711/trello-color-blind-friendly-mode-makes">Little Big Details: Trello - Color Blind Friendly Mode makes labels distinguishable by pattern.</a></li>
<li><a id="cite-6" href="http://www.npr.org/2013/01/18/169708761/edward-tufte-wants-you-to-see-better">NPR: Edward Tufte Wants You to See Better</a></li>
<li><a id="cite-7" href="https://web.archive.org/web/20070814054750/http://www.colorschemer.com/blog/2007/07/17/why-food-companies-use-red-colors">ColorSchemer (via Archive.org): Why food companies use red colors</a></li>
<li><a id="cite-8" href="http://getbootstrap.com">Bootstrap</a></li>
<li><a id="cite-9" href="http://getbootstrap.com/css/#helper-classes">Bootstrap: CSS Helper Classes</a></li>
<li><a id="cite-10" href="http://tympanus.net/codrops/2012/09/17/build-a-color-scheme-the-fundamentals">Codrops: Build a Color Scheme: The Fundamentals</a></li>
<li><a id="cite-11" href="http://colorschemedesigner.com/">Color Scheme Designer</a></li>
<li><a id="cite-12" href="https://kuler.adobe.com/create/color-wheel/">Adobe Kuler: Color Wheel</a></li>
<li><a id="cite-13" href="http://fontsinuse.com/uses/2575/medium">Fonts In Use: Medium</a></li>
</ol>
<hr>
<nav class="chapter-navigation">
<a class="previous-chapter" href="../3-tables">
<span class="number">3</span>
<span class="title">Tables</span>
</a>
<a class="next-chapter" href="../5-typography">
<span class="number">5</span>
<span class="title">Typography</span>
</a>
</nav>
</div>
</div>
<script src="../../js/footer.js"></script>
</body>
</html>
================================================
FILE: chapters/5-typography/index.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Typography — Chapter 5 — Magic of CSS — Adam Schwartz</title>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<link rel="icon" href="/magic-of-css/favicon.ico">
<link rel="stylesheet" href="../../css/base.css">
<link rel="stylesheet" href="../../css/logo.css">
<link rel="stylesheet" href="../../css/chapter.css">
<script src="../../js/chapters.js"></script>
</head>
<body>
<div class="page">
<a class="logo" href="/../.."><h1 class="the-magic-of">The Magic of CSS</h1><div class="css-rainbow"><div class="css-letter css-rainbow-c"><div class="rainbow"><div class="bands"><div class="red"></div><div class="orange"></div><div class="yellow"></div><div class="green"></div><div class="blue"></div><div class="purple"></div></div></div></div><div class="css-letter css-rainbow-s css-rainbow-s-1"><div class="top-half"><div class="rainbow"><div class="bands"><div class="red"></div><div class="orange"></div><div class="yellow"></div><div class="green"></div><div class="blue"></div><div class="purple"></div></div></div></div><div class="bottom-half"><div class="rainbow"><div class="bands"><div class="purple"></div><div class="blue"></div><div class="green"></div><div class="yellow"></div><div class="orange"></div><div class="red"></div></div></div></div></div><div class="css-letter css-rainbow-s css-rainbow-s-2"><div class="top-half"><div class="rainbow"><div class="bands"><div class="red"></div><div class="orange"></div><div class="yellow"></div><div class="green"></div><div class="blue"></div><div class="purple"></div></div></div></div><div class="bottom-half"><div class="rainbow"><div class="bands"><div class="purple"></div><div class="blue"></div><div class="green"></div><div class="yellow"></div><div class="orange"></div><div class="red"></div></div></div></div></div></div></a>
<div class="chapter">
<h1>
<span class="number">Chapter 5</span>
<span class="title">Typography</span>
</h1>
<h2>Typography is hard</h2>
<p>First off, give yourself a pat on the back. You’ve made it this far. You’re reading about typography!</p>
<p>Now take a moment to realize that <em>most of the things you look at every day are type</em>. So before discussing typography, let’s look at it.</p>
<p>Take a moment and just fly through some of these beautiful typographically-based design collections:</p>
<ul>
<li><a href="http://www.awwwards.com/websites/typography/">Awwwards: Typography in Web Design</a></li>
<li><a href="http://webdesign.tutsplus.com/articles/10-examples-of-inspirational-typography-on-the-web--webdesign-904">Tutsplus: 10 Examples of Inspirational Typography on the Web</a></li>
<li><a href="http://webdesignledger.com/inspiration/21-beautiful-examples-of-typography-in-web-design">Web Design Ledger: 21 Beautiful Examples of Typography in Web Design</a></li>
<li><a href="http://www.smashingmagazine.com/2013/08/06/beautiful-typography-web-design/">Smashing Magazine: A Journey Through Beautiful Typography In Web Design</a></li>
<li><a href="http://web3canvas.com/20-beautifully-designed-typography-website-inspiration-2013/">Web3Canvas: 20 beautifully designed Typography Website Inspiration 2013</a></li>
</ul>
<h2>Seeing</h2>
<p>As with <a href="../4-color">color</a>, designing well with typography requires using your eyes. Really <em>see</em> the shape of each glyph. Notice the negative space between glyphs. You have more control over these things than you might think. And over the course of the next few chapters, I’m going to show you how.</p>
<h2>Basic CSS Typography Tools</h2>
<p>The basic tools in your toolkit consist of the following:</p>
<ul>
<li>
<p>Font properties</p>
<ul>
<li><code>font-family</code> — <span style="font-family: inherit">inherit</span>, <span style="font-family: serif">serif</span>, <span style="font-family: monospace">monospace</span></li>
<li><code>font-size</code> — <span style="font-size: inherit">inherit</span>, <span style="font-size: 18px; line-height: 1em">18px</span>, <span style="font-size: 10px; line-height: 1em">10px</span></li>
<li><code>font-weight</code> — <span style="font-weight: inherit">inherit</span>, <span style="font-weight: bold">bold</span>, <span style="font-weight: 100">100</span></li>
<li><code>font-style</code> — <span style="font-style: inherit">inherit</span>, <span style="font-style: italic">italic</span></li>
<li><code>font-variant</code> — <span style="font-variant: inherit">inherit</span>, <span style="font-variant: small-caps">small-caps</span></li>
</ul>
</li>
<li>
<p>Text properties</p>
<ul>
<li><code>text-align</code> — <span style="text-align: inherit">inherit</span>, <span style="text-align: center; display: inline-block; width: 10em; box-shadow: 0 0 0 1px #ccc">center</span></li>
<li><code>text-decoration</code> — <span style="text-decoration: inherit">inherit</span>, <span style="text-decoration: underline">underline</span>, <span style="text-decoration: overline">overline</span>, <span style="text-decoration: line-through">line-through</span></li>
<li><code>text-indent</code> — <span style="text-indent: inherit">inherit</span>, <span style="text-indent: 50px; display: inline-block">50px</span></li>
<li><code>text-shadow</code> — <span style="text-shadow: inherit">inherit</span>, <span style="text-shadow: 0 1px 3px red">0 1px 3px red</span></li>
<li><code>text-transform</code> — <span style="text-transform: inherit">inherit</span>, <span style="text-transform: uppercase">uppercase</span></li>
</ul>
</li>
<li>
<p>Miscellaneous</p>
<ul>
<li><code>letter-spacing</code> — <span style="letter-spacing: inherit">inherit</span>, <span style="letter-spacing: 5px">5px</span></li>
<li><code>white-space</code> — <span style="white-space: inherit">inherit</span>, <span style="white-space: pre">pre pre</span></li>
<li><code>line-height</code> — <span style="line-height: inherit; display: inline-block; box-shadow: 0 0 0 1px #ccc">inherit</span>, <span style="line-height: .75em; display: inline-block; box-shadow: 0 0 0 1px #ccc">.75em</span></li>
<li><code>word-spacing</code> — <span style="word-spacing: inherit">inherit</span>, <span style="word-spacing: 100px">100px 100px</span></li>
</ul>
</li>
</ul>
<p>Now that you have a basic idea of what is possible, let’s look at a few combinations of these properties.</p>
<style>
.typography-example {
line-height: normal
}
</style>
<h2>Examples</h2>
<span><!-- prevent h2 + h3 selector from applying --></span>
<h3>Example 1: Light, uppercase, with spacing</h3>
<p>Light text colors on dark backgrounds tend to feel as if they have a heavier weight. So with this example of <code style="background-image: linear-gradient(135deg, #723362, #9d223c); color: #fff; background-color: #9d223c; border-radius: .1875rem; margin: 0 .05rem 0 .13rem; font-family: inherit">white on purple</code>, we went with a <code>font-weight: 300</code>.</p>
<p>Using all uppercased letters can be a powerful effect, but you’ll want to use it sparingly. One thing that can happen with uppercased words is <span style="text-transform: uppercase">the letters can feel jammed together</span>. This is because the default kerning and letter-spacing is meant for mostly-lowercased words. To compensate, and also to add a little more gravitas, we added a generous <code>letter-spacing: .4em</code>.</p>
<p>As can be seen in the <a href="../../potions/letter-spacing/">letter spacing potion</a>, <code>letter-spacing</code> and <code>text-align</code> don’t play so nicely together because the spacing is added to the right of each letter. To compensate for this, when using these two properties together, we add a <code>padding-left</code> to match the chosen letter-spacing (in this case <code>.4em</code>).</p>
<div class="example-wrapper typography-example-wrapper">
<style>
.typography-example-1 {
background-image: linear-gradient(135deg, #723362, #9d223c);
background-color: #9d223c;
color: #fff;
padding: 1em 0;
font-weight: 300;
font-size: 1.8em;
text-transform: uppercase;
text-align: center;
letter-spacing: .4em;
padding-left: .4em
}
</style>
<pre><code>.typography-example-1 {
background-image: linear-gradient(135deg, #723362, #9d223c);
background-color: #9d223c;
color: #fff;
padding: 1em 0;
font-weight: 300;
font-size: 1.8em;
text-transform: uppercase;
text-align: center;
letter-spacing: .4em;
padding-left: .4em
}</code></pre>
<div class="example typography-example typography-example-1">
Example One
</div>
</div>
<h3>Example 2: Contrasting weights and styles</h3>
<p>In this next example, we show how two lines of text interact with each other.</p>
<p>The first line is given a similar treatment as Example 1, but with a heavier weight of <code>700</code>. To contrast this, the second line is given a thinner weight, <code>300</code>, an <code>italic</code> font style, and a lighter color, <code>#888</code><code class="color"><span style="background: #ccc"></span></code>.</p>
<div class="example-wrapper typography-example-wrapper">
<style>
.typography-example-2 {
background: #fff;
color: #000;
border: .5em solid;
font-size: 1.5em;
padding: 1em 0;
text-align: center
}
.typography-example-2 .title {
font-weight: 700;
text-transform: uppercase;
letter-spacing: .4em;
padding-left: .4em
}
.typography-example-2 .author {
color: #888;
font-size: .7em;
font-weight: 300;
font-style: italic;
letter-spacing: .12em;
padding-left: .12em
}
</style>
<pre><code>.typography-example-2 {
background: #fff;
color: #000;
border: .5em solid;
font-size: 1.5em;
padding: 1em 0;
text-align: center
}
.typography-example-2 .title {
font-weight: 700;
text-transform: uppercase;
letter-spacing: .4em;
padding-left: .4em
}
.typography-example-2 .author {
color: #888;
font-size: .7em;
font-weight: 300;
font-style: italic;
letter-spacing: .12em;
padding-left: .12em
}</code></pre>
<div class="example typography-example typography-example-2">
<div class="title">Example</div>
<div class="author">by Adam Schwartz</div>
</div>
</div>
<style>
.a-little-fun span {
display: inline-block;
-webkit-animation: a-little-fun-wiggle 1s linear infinite alternate;
}
@-webkit-keyframes a-little-fun-wiggle {
from { -webkit-transform: rotateZ(-20deg) }
to { -webkit-transform: rotateZ(20deg) }
}
</style>
<h3>Example 3: Individual letter treatment</h3>
<p>Sometimes you want to <span class="a-little-fun"><span>h</span><span>a</span><span>v</span><span>e</span><span> </span><span>a</span><span> </span><span>l</span><span>i</span><span>t</span><span>t</span><span>l</span><span>e</span><span> </span><span>f</span><span>u</span><span>n</span></span> with type. <a href="http://letteringjs.com">Lettering.js</a> is a great little tool for doing just that. But if you’re willing to <a href="https://www.youtube.com/watch?v=WXuBgSpLpK4">type out a bunch</a> of <code>span</code> wrappers for every letter yourself, you can do the same sort of thing without javascript!</p>
<div class="example-wrapper typography-example-wrapper">
<style>
.typography-example-3 {
border: .2em solid #ff3283;
font-size: 3em;
text-align: center;
padding: .2em;
color: #fff
}
.typography-example-3 span {
display: inline-block;
width: 20%;
padding: .8125rem
}
.typography-example-3 span:nth-child(1) { background: #ff3283 }
.typography-example-3 span:nth-child(2) { background: #ff716a }
.typography-example-3 span:nth-child(3) { background: #8ebd14 }
.typography-example-3 span:nth-child(4) { background: #0085ae }
.typography-example-3 span:nth-child(5) { background: #6335e6 }
</style>
<pre><code>.typography-example-3 {
border: .2em solid #ff4136;
font-size: 3em;
text-align: center;
padding: .2em;
color: #fff
}
.typography-example-3 span {
display: inline-block;
width: 20%;
padding: .8125rem
}
.typography-example-3 span:nth-child(1) { background: #ff4136 }
.typography-example-3 span:nth-child(2) { background: #ff851b }
.typography-example-3 span:nth-child(3) { background: #2ecc40 }
.typography-example-3 span:nth-child(4) { background: #0074d9 }
.typography-example-3 span:nth-child(5) { background: #b10dc9 }</code></pre>
<div class="example typography-example typography-example-3">
<span>M</span><span>A</span><span>G</span><span>I</span><span>C</span>
</div>
</div>
<h3>Typography lives everywhere</h3>
<p>Hopefully these few examples have given you an idea of what’s possible with the various typographical CSS properties. Typography is such a crucial part of design that a lot of typographical thinking and concepts are embedded in the other chapters. We’ll continue to explore typography as we go.</p>
<style>
.typography-example-4 {
background: #fff;
border: .125em dashed #ccc;
color: #aaa;
padding: 1em 0;
text-align: center;
font-weight: 400;
font-size: 1.5em
}
</style>
<div class="example typography-example typography-example-4">
What will you design?
</div>
<h3>Butterick’s Practical Typography</h3>
<p>For more fun with typography, check out the amazing resources below. In particular, glance over <a href="http://practicaltypography.com">Butterick’s Practical Typography</a><sup><a href="#cite-1">[1]</a></sup>. It’s a must-read for anyone with an interest in typography.</p>
<h3>Further reading</h3>
<ul>
<li><a href="http://practicaltypography.com">Butterick’s Practical Typography</a></li>
<li><a href="http://www.newnet-soft.com/blog/csstypography">CSS Typography Cheat Sheet</a></li>
<li><a href="http://type-scale.com">Type Scale</a></li>
<li><a href="http://tympanus.net/codrops/2012/09/26/make-a-statement-with-type/">Codedrops: Make a Statement with Type</a></li>
</ul>
<h3>Citations</h3>
<ol>
<li><a id="cite-1" href="http://practicaltypography.com">Butterick’s Practical Typography</a></li>
</ol>
<hr>
<nav class="chapter-navigation">
<a class="previous-chapter" href="../4-color">
<span class="number">4</span>
<span class="title">Color</span>
</a>
<a class="next-chapter" href="../6-transitions">
<span class="number">6</span>
<span class="title">Transitions</span>
</a>
</nav>
</div>
</div>
<script src="../../js/footer.js"></script>
</body>
</html>
================================================
FILE: chapters/6-transitions/index.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Transitions — Chapter 6 — Magic of CSS — Adam Schwartz</title>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<link rel="icon" href="/magic-of-css/favicon.ico">
<link rel="stylesheet" href="../../css/base.css">
<link rel="stylesheet" href="../../css/logo.css">
<link rel="stylesheet" href="../../css/chapter.css">
<script src="../../js/chapters.js"></script>
</head>
<body>
<div class="page">
<a class="logo" href="/../.."><h1 class="the-magic-of">The Magic of CSS</h1><div class="css-rainbow"><div class="css-letter css-rainbow-c"><div class="rainbow"><div class="bands"></div></div></div><div class="css-letter css-rainbow-s css-rainbow-s-1"><div class="top-half"><div class="rainbow"><div class="bands"></div></div></div><div class="bottom-half"><div class="rainbow"><div class="bands"></div></div></div></div><div class="css-letter css-rainbow-s css-rainbow-s-2"><div class="top-half"><div class="rainbow"><div class="bands"></div></div></div><div class="bottom-half"><div class="rainbow"><div class="bands"></div></div></div></div></div></a>
<div class="chapter">
<h1>
<span class="number">Chapter 6</span>
<span class="title">Transitions</span>
</h1>
<h3>“All you need to know about CSS Transitions”</h3>
<p>Before reading this chapter, please read <a href="https://blog.alexmaccaw.com/all-you-need-to-know-about-css-transitions/">All you need to know about CSS Transitions</a> by Alex MacCaw. This is a fantastic resource and covers much of what we’d like to cover.</p>
<hr>
<h2>Transitions</h2>
<p>CSS transitions are the ideal solution for transitioning a CSS property (or set of properties) from one value to another value along some easing path.</p>
<p>Now, together, let’s combine this knowledge with what we’ve learned in the previous chapters on <a href="../4-color">Color</a> and <a href="../5-typography">Typography</a>.</p>
<style>
.typography-example {
line-height: normal;
margin-bottom: 8rem
}
.typography-example {
position: relative
}
.typography-example,
.typography-example * {
cursor: default
}
.typography-example::before {
content: "Hover to see transition";
text-transform: uppercase;
position: absolute;
top: .625rem;
left: .625rem;
font-size: .625rem;
letter-spacing: .1em;
transition: opacity 200ms;
transition-delay: 2000ms
}
.typography-example:hover::before {
transition-delay: 0ms;
opacity: 0
}
/* Workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=990340 */
@-moz-document url-prefix() {
.typography-example {
overflow: hidden
}
}
</style>
<h2>Examples</h2>
<span><!-- prevent h2 + h3 selector from applying --></span>
<h3>Example 1: Random individual letter fade</h3>
<p>One extremely powerful tool at your disposal is <code>transition-delay</code>. Transition delays allow you to delay the start of when a transition occurs. In this first example, we set pseudo-random delays for the <code>opacity</code> transitions on each letter, creating a reveal effect that is both subtle and attractive.</p>
<div class="example-wrapper typography-example-wrapper">
<style>
.typography-example-1 {
background-image: linear-gradient(135deg, #723362, #9d223c);
background-color: #9d223c;
color: #fff;
padding: 1em 0;
text-align: center;
font-weight: 300;
text-transform: uppercase;
letter-spacing: .4em;
padding-left: .4em;
font-size: 1.8em;
margin-top: 2.5rem
}
.typography-example-1 span {
opacity: 0;
transition: opacity 1300ms
}
.typography-example-1 span:nth-child(1) { transition-delay: 200ms }
.typography-example-1 span:nth-child(2) { transition-delay: 1200ms }
.typography-example-1 span:nth-child(3) { transition-delay: 800ms }
.typography-example-1 span:nth-child(4) { transition-delay: 300ms }
.typography-example-1 span:nth-child(5) { transition-delay: 700ms }
.typography-example-1 span:nth-child(6) { transition-delay: 600ms }
.typography-example-1 span:nth-child(7) { transition-delay: 400ms }
.typography-example-1 span:nth-child(8) { transition-delay: 900ms }
.typography-example-1 span:nth-child(9) { transition-delay: 700ms }
.typography-example-1 span:nth-child(10) { transition-delay: 50ms }
.typography-example-1:hover span {
opacity: 1
}
</style>
<pre><code>.ex span {
opacity: 0;
transition: opacity 1300ms
}
.ex span:nth-child(1) { transition-delay: 200ms }
.ex span:nth-child(2) { transition-delay: 1200ms }
.ex span:nth-child(3) { transition-delay: 800ms }
.ex span:nth-child(4) { transition-delay: 300ms }
.ex span:nth-child(5) { transition-delay: 700ms }
.ex span:nth-child(6) { transition-delay: 600ms }
.ex span:nth-child(7) { transition-delay: 400ms }
.ex span:nth-child(8) { transition-delay: 900ms }
.ex span:nth-child(9) { transition-delay: 700ms }
.ex span:nth-child(10) { transition-delay: 50ms }
.ex:hover span {
opacity: 1
}</code></pre>
<div class="example typography-example typography-example-1">
<span>E</span><span>x</span><span>a</span><span>m</span><span>p</span><span>l</span><span>e</span> <span>O</span><span>n</span><span>e</span>
</div>
</div>
<h3>Example 2: Multiple transitions and delays</h3>
<p>CSS transitions really shine when they’re combined. In this example, we specify two transitions, one for <code>-webkit-transform</code> and one for <code>opacity</code>. They are written as part of the same <code>transition</code> declaration, separated with commas.</p>
<pre><code>.ex .title span,
.ex .author span {
/* ... */
transition: -webkit-transform 800ms, opacity 800ms
}</code></pre>
<p>Since we specified two transitions, we also must specify two transition delays. They are written similarly.</p>
<pre><code>.ex .title span:nth-child(1) { transition-delay: 360ms, 300ms }
.ex .title span:nth-child(2) { transition-delay: 420ms, 300ms }
.ex .title span:nth-child(3) { transition-delay: 480ms, 300ms }
/* ... */
</code></pre>
<p>Together, these transitions and their delays allow us to create a beautiful wave effect with the letters in this example.</p>
<div class="example-wrapper typography-example-wrapper">
<style>
.typography-example-2 {
background: #fff;
border: .5em solid #000;
color: #000;
padding: 1em 0;
text-align: center;
font-weight: 700;
text-transform: uppercase;
font-size: 1.5em
}
.typography-example-2 .title {
display: block;
letter-spacing: .4em;
padding-left: .4em
}
.typography-example-2 .author {
font-style: italic;
font-weight: 300;
color: #888;
font-size: .7em;
text-transform: none;
letter-spacing: .12em;
padding-left: .12em
}
.typography-example-2 {
overflow: hidden
}
.typography-example-2 .title span,
.typography-example-2 .author span {
display: inline-block;
opacity: 0;
transition: -webkit-transform 800ms, opacity 800ms
}
.typography-example-2 .title span {
-webkit-transform: translateZ(0) translateY(-6rem)
}
.typography-example-2 .author span {
-webkit-transform: translateZ(0) translateY(6rem)
}
.typography-example-2:hover .title span,
.typography-example-2:hover .author span {
opacity: 1;
transition: -webkit-transform 800ms, opacity 1200ms;
-webkit-transform: translateZ(0) translateY(0)
}
.typography-example-2 .title span:nth-child(1) { transition-delay: 360ms, 300ms }
.typography-example-2 .title span:nth-child(2) { transition-delay: 420ms, 300ms }
.typography-example-2 .title span:nth-child(3) { transition-delay: 480ms, 300ms }
.typography-example-2 .title span:nth-child(4) { transition-delay: 540ms, 300ms }
.typography-example-2 .title span:nth-child(5) { transition-delay: 600ms, 300ms }
.typography-example-2 .title span:nth-child(6) { transition-delay: 660ms, 300ms }
.typography-example-2 .title span:nth-child(7) { transition-delay: 720ms, 300ms }
.typography-example-2 .author span:nth-child(1) { transition-delay: 420ms, 0ms }
.typography-example-2 .author span:nth-child(2) { transition-delay: 390ms, 0ms }
.typography-example-2 .author span:nth-child(3) { transition-delay: 360ms, 0ms }
.typography-example-2 .author span:nth-child(4) { transition-delay: 330ms, 0ms }
.typography-example-2 .author span:nth-child(5) { transition-delay: 300ms, 0ms }
.typography-example-2 .author span:nth-child(6) { transition-delay: 270ms, 0ms }
.typography-example-2 .author span:nth-child(7) { transition-delay: 240ms, 0ms }
.typography-example-2 .author span:nth-child(8) { transition-delay: 210ms, 0ms }
.typography-example-2 .author span:nth-child(9) { transition-delay: 180ms, 0ms }
.typography-example-2 .author span:nth-child(10) { transition-delay: 150ms, 0ms }
.typography-example-2 .author span:nth-child(11) { transition-delay: 120ms, 0ms }
.typography-example-2 .author span:nth-child(12) { transition-delay: 90ms, 0ms }
.typography-example-2 .author span:nth-child(13) { transition-delay: 60ms, 0ms }
.typography-example-2 .author span:nth-child(14) { transition-delay: 30ms, 0ms }
.typography-example-2:hover .title span,
.typography-example-2:hover .author span {
transition-delay: 0;
}
/* Firefox styles */
@-moz-document url-prefix() {
.typography-example-2 .title span,
.typography-example-2 .author span {
transition: -moz-transform 800ms, opacity 800ms
}
.typography-example-2 .title span {
-moz-transform: translateZ(0) translateY(-6rem)
}
.typography-example-2 .author span {
-moz-transform: translateZ(0) translateY(6rem)
}
.typography-example-2:hover .title span,
.typography-example-2:hover .author span {
transition: -moz-transform 800ms, opacity 1200ms;
-moz-transform: translateZ(0) translateY(0)
}
}
</style>
<pre><code>.ex .title span,
.ex .author span {
display: inline-block;
opacity: 0;
transition: -webkit-transform 800ms, opacity 800ms
}
.ex .title span {
-webkit-transform: translateZ(0) translateY(-6rem)
}
.ex .author span {
-webkit-transform: translateZ(0) translateY(6rem)
}
.ex:hover .title span,
.ex:hover .author span {
opacity: 1;
transition: -webkit-transform 800ms, opacity 1200ms;
-webkit-transform: translateZ(0) translateY(0)
}
.ex .title span:nth-child(1) { transition-delay: 360ms, 300ms }
.ex .title span:nth-child(2) { transition-delay: 420ms, 300ms }
.ex .title span:nth-child(3) { transition-delay: 480ms, 300ms }
.ex .title span:nth-child(4) { transition-delay: 540ms, 300ms }
.ex .title span:nth-child(5) { transition-delay: 600ms, 300ms }
.ex .title span:nth-child(6) { transition-delay: 660ms, 300ms }
.ex .title span:nth-child(7) { transition-delay: 720ms, 300ms }
.ex .author span:nth-child(1) { transition-delay: 420ms, 0ms }
.ex .author span:nth-child(2) { transition-delay: 390ms, 0ms }
.ex .author span:nth-child(3) { transition-delay: 360ms, 0ms }
.ex .author span:nth-child(4) { transition-delay: 330ms, 0ms }
.ex .author span:nth-child(5) { transition-delay: 300ms, 0ms }
.ex .author span:nth-child(6) { transition-delay: 270ms, 0ms }
.ex .author span:nth-child(7) { transition-delay: 240ms, 0ms }
.ex .author span:nth-child(8) { transition-delay: 210ms, 0ms }
.ex .author span:nth-child(9) { transition-delay: 180ms, 0ms }
.ex .author span:nth-child(10) { transition-delay: 150ms, 0ms }
.ex .author span:nth-child(11) { transition-delay: 120ms, 0ms }
.ex .author span:nth-child(12) { transition-delay: 90ms, 0ms }
.ex .author span:nth-child(13) { transition-delay: 60ms, 0ms }
.ex .author span:nth-child(14) { transition-delay: 30ms, 0ms }
.ex:hover .title span,
.ex:hover .author span {
transition-delay: 0
}</code></pre>
<div class="example typography-example typography-example-2">
<span class="title">
<span>E</span><span>x</span><span>a</span><span>m</span><span>p</span><span>l</span><span>e</span>
</span>
<span class="author">
<span>b</span><span>y</span> <span>A</span><span>d</span><span>a</span><span>m</span> <span>S</span><span>c</span><span>h</span><span>w</span><span>a</span><span>r</span><span>t</span><span>z</span>
</span>
</div>
</div>
<h3>Example 3D</h3>
<p>And just in case you were wondering: transitions work on 3D transforms too.</p>
<div class="example-wrapper typography-example-wrapper">
<style>
.typography-example-3 {
border: .2em solid #ff3283;
font-size: 3em;
text-align: center;
padding: .2em;
color: #fff
}
.typography-example-3 .letter {
display: inline-block;
width: 20%;
padding: .8125rem;
position: relative;
-webkit-perspective: 20rem
}
.typography-example-3 .letter::before {
content: "\00a0"
}
.typography-example-3 .front,
.typography-example-3 .back {
display: block;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
line-height: 1.9;
-webkit-backface-visibility: hidden;
transition: -webkit-transform 800ms
}
.typography-example-3 .letter:nth-child(1) .front { background: #ff3283 }
.typography-example-3 .letter:nth-child(2) .front { background: #ff716a }
.typography-example-3 .letter:nth-child(3) .front { background: #8ebd14 }
.typography-example-3 .letter:nth-child(4) .front { background: #0085ae }
.typography-example-3 .letter:nth-child(5) .front { background: #6335e6 }
.typography-example-3 .back {
border: .5rem solid;
background: #fff;
color: #000;
-webkit-transform: translateZ(0) rotateY(-180deg);
line-height: 1.6
}
.typography-example-3 .letter:nth-child(1) .back { border-color: #ff3283 }
.typography-example-3 .letter:nth-child(2) .back { border-color: #ff716a }
.typography-example-3 .letter:nth-child(3) .back { border-color: #8ebd14; background: #8ebd14; color: #fff }
.typography-example-3 .letter:nth-child(4) .back { border-color: #0085ae; background: #0085ae; color: #fff }
.typography-example-3 .letter:nth-child(5) .back { border-color: #6335e6; background: #6335e6; color: #fff }
.typography-example-3:hover .back {
-webkit-transform: translateZ(0) rotateY(0deg)
}
.typography-example-3:hover .front {
-webkit-transform: translateZ(0) rotateY(180deg)
}
.typography-example-3 .letter:nth-child(1) span { transition-delay: 200ms }
.typography-example-3 .letter:nth-child(2) span { transition-delay: 400ms }
.typography-example-3 .letter:nth-child(3) span { transition-delay: 600ms }
.typography-example-3 .letter:nth-child(4) span { transition-delay: 800ms }
.typography-example-3 .letter:nth-child(5) span { transition-delay: 1000ms }
.typography-example-3::before {
background: #ff3283;
z-index: 1
}
/* Firefox styles */
@-moz-document url-prefix() {
.typography-example-3 .letter {
-moz-perspective: 20rem
}
.typography-example-3 .front,
.typography-example-3 .back {
-moz-backface-visibility: hidden;
transition: -moz-transform 800ms
}
.typography-example-3 .back {
-moz-transform: translateZ(0) rotateY(-180deg)
}
.typography-example-3:hover .back {
-moz-transform: translateZ(0) rotateY(0deg)
}
.typography-example-3:hover .front {
-moz-transform: translateZ(0) rotateY(180deg)
}
}
</style>
<pre><code>.ex .letter {
-webkit-perspective: 20rem
}
.ex .front,
.ex .back {
-webkit-backface-visibility: hidden;
transition: -webkit-transform 800ms
}
.ex .back {
-webkit-transform: translateZ(0) rotateY(-180deg)
}
.ex:hover .back {
-webkit-transform: translateZ(0) rotateY(0deg)
}
.ex:hover .front {
-webkit-transform: translateZ(0) rotateY(180deg)
}
.ex .letter:nth-child(1) span { transition-delay: 200ms }
.ex .letter:nth-child(2) span { transition-delay: 400ms }
.ex .letter:nth-child(3) span { transition-delay: 600ms }
.ex .letter:nth-child(4) span { transition-delay: 800ms }
.ex .letter:nth-child(5) span { transition-delay: 1000ms }</code></pre>
<div class="example typography-example typography-example-3">
<span class="letter">
<span class="back">o</span>
<span class="front">M</span>
</span><!--
--><span class="letter">
<span class="back">f</span>
<span class="front">A</span>
</span><!--
--><span class="letter">
<span class="back">C</span>
<span class="front">G</span>
</span><!--
--><span class="letter">
<span class="back">S</span>
<span class="front">I</span>
</span><!--
--><span class="letter">
<span class="back">S</span>
<span class="front">C</span>
</span>
</div>
</div>
<p>Of course, this is just the tip of the iceberg. Colors, gradients, sizes, positions, orientations, etc., can all be transitioned simultaneously. In addition you have delays and custom easing functions right at your fingertips. CSS transitions are so easy to work with. Trust that the browser will do the right thing when you transition a CSS property, because it usually does.</p>
<h3 class="magic">Radio button accordion</h3>
<p>Combining HTML state with CSS transitions can make for rich interactions. Here we use the <code>:checked</code> pseudo-selector on radio buttons to style elements which follow them. This technique is often referred to as “<a href="https://www.google.com/search?q=%22checkbox+hack%22">The Checkbox Hack</a>”, but it could work with just about any element which can hold state via some pseudo-selector (<code>:checked</code>, <code>:focus</code>, etc.).</p>
<p>There’s a lot of subtlety in this example, but the main idea is this: each accordion baffle has a <code>label</code> whose <code>for</code> attribute matches the <code>id</code> of a radio button. So, three baffles, three radio buttons. These radio buttons are placed in the document just before the baffle contents, so that we can use the adjacent selector <code> + </code> to style differently baffles which appear after <code>:checked</code> radios.</p>
<pre><code>.accordion .baffle {
height: 0
}
.accordion input[type="radio"]:checked + .baffle {
height: 10em
}</code></pre>
<p>Clicking the baffle label checks the radio button (and unchecks whichever radio button was previously checked) triggering the opening/closing of the appropriate baffle.</p>
<p>And voilà. An accordion with only HTML and CSS.</p>
<style>
.accordion-example .accordion input[type="radio"] {
position: absolute;
left: -9999rem;
}
.accordion-example .accordion label {
display: block;
background: #4f6f8b;
color: #fff;
text-align: center;
padding: 1rem;
font-size: .8em;
letter-spacing: .13em;
padding-left: .13em;
padding-right: 0;
text-transform: uppercase;
cursor: pointer;
height: 3.3rem;
font-weight: 300;
transition: background 400ms, color 400ms, border-radius 400ms;
}
.accordion-example .accordion label:hover {
background: #385670
}
.accordion-example .accordion .baffle {
position: relative;
height: 3.3rem;
overflow: hidden;
transition: height 400ms;
-webkit-transform: translateZ(0);
}
.accordion-example .accordion .baffle-inner {
padding: 1.25rem;
background: #eee;
position: absolute;
top: 3.3rem;
left: 0;
height: 13.5rem;
-webkit-overflow-scrolling: touch;
overflow: scroll;
overflow-y: scroll;
overflow-x: hidden
}
.accordion-example .accordion .baffle:first-of-type label {
border-radius: .25rem .25rem 0 0
}
.accordion-example .accordion .baffle:last-of-type label,
.accordion-example .accordion .baffle:last-of-type .baffle-inner {
border-radius: 0 0 .25rem .25rem
}
.accordion-example .accordion .baffle-inner :first-child {
margin-top: 0
}
.accordion-example .accordion .baffle-inner :last-child {
margin-bottom: 0
}
.accordion-example .accordion input[type="radio"]:checked + .baffle {
height: 16.8rem
}
.accordion-example .accordion input[type="radio"]:checked + .baffle label {
background: #eee;
color: inherit;
box-shadow: inset 0 -1px rgba(0, 0, 0, .15);
font-weight: 300
}
.accordion-example .accordion input[type="radio"]:checked + .baffle:not(:first-of-type) label {
border-radius: 0
}
.accordion-example .accordion input[type="radio"]:not(:checked) + .baffle + input[type="radio"]:not(:checked) + .baffle label {
box-shadow: inset 0 1px rgba(0, 0, 0, .15);
}
.accordion-example ::-webkit-scrollbar {
width: .9375rem
}
.accordion-example ::-webkit-scrollbar-thumb {
background: #849cb1;
border: solid #eee;
border-width: .375rem .375rem .375rem 0;
border-radius: 0 .375rem .375rem 0
}
.accordion-example ::-webkit-scrollbar-thumb:window-inactive {
background: #aaa
}
</style>
<div class="accordion-example">
<div class="accordion">
<input type="radio" id="radio-option-1" name="accordion-radios" checked>
<div class="baffle">
<label for="radio-option-1">Accordion</label>
<div class="baffle-inner">
Accordions (from 19th century German Akkordion, from Akkord - “musical chord, concord of sounds”) are a family of box-shaped musical instruments of the bellows-driven free-reed aerophone type, colloquially referred to as a squeezebox. A person who plays the accordion is called an accordionist. The concertina and bandoneón are related; the harmonium and American reed organ are in the same family.
</div>
</div>
<input type="radio" id="radio-option-2" name="accordion-radios">
<div class="baffle">
<label for="radio-option-2">Construction</label>
<div class="baffle-inner">
<p>Accordions have many configurations and types. What may be technically possible to do with one accordion could be impossible with another:</p>
<ul>
<li>Some accordions are bisonoric, producing different pitches depending on the direction of bellows movement</li>
<li>Others are unisonoric and produce the same pitch in both directions</li>
<li>Some use a chromatic buttonboard for the right-hand manual</li>
<li>Others use a diatonic buttonboard for the right-hand manual</li>
<li>Yet others use a piano-style musical keyboard for the right-hand manual</li>
<li>Some can play in different registers</li>
<li>Craftsmen and technicians may tune the same registers differently, “personalizing” the end result, such as an organ technician might voice a particular instrument</li>
</ul>
</div>
</div>
<input type="radio" id="radio-option-3" name="accordion-radios">
<div class="baffle">
<label for="radio-option-3">History</label>
<div class="baffle-inner">
<p>The accordion is a free reed instrument and is in the same family as other instruments such as the sheng and khaen. The sheng and khaen are both much older than the accordion and this type of reed did inspire the kind of free reeds in use in the accordion as we know it today.</p>
<p>The accordion’s basic form is believed to have been invented in Berlin in 1822 by Christian Friedrich Ludwig Buschmann, although one instrument has been recently discovered that appears to have been built earlier.</p>
</div>
</div>
</div>
</div>
<h3>Transition Inspiration</h3>
<p>If you’re looking for more inspiration on what is possible with CSS transitions, check out these amazing demos from Codrops:</p>
<ul>
<li><a href="http://tympanus.net/Development/SidebarTransitions">Sidebar Transitions</a></li>
<li><a href="http://tympanus.net/Development/PageTransitions">Page Transitions</a></li>
<li><a href="http://tympanus.net/Development/HeaderEffects">Header Effects</a></li>
<li><a href="http://tympanus.net/Development/CreativeLinkEffects">Creative Link Effects</a></li>
<li><a href="http://tympanus.net/Development/StackEffects">Simple Stack Effects</a></li>
<li><a href="http://tympanus.net/Development/ThumbnailGridAnimations">Animations for Thumbnail Grids</a></li>
<li><a href="http://tympanus.net/Development/GridLoadingEffects">Loading Effects for Grid Items</a></li>
</ul>
<h3>jQuery.Transit</h3>
<p>For those of you who like a little JS to spice up your CSS, check out <a href="https://github.com/rstacruz">rstacruz</a>’s <a href="https://github.com/rstacruz/jquery.transit">jquery.transit</a>. For simple, static transitions (<em>oxymoron?</em>), it’s overkill. But you may find it really useful if you’re doing transitions which have dynamic or user-generated CSS property values.</p>
<h3>Further reading</h3>
<ul>
<li><a href="http://caniuse.com/css-transitions">Can I Use: CSS Transitions</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_transitions">MDN: Using CSS transitions</a></li>
</ul>
<!-- TODO -->
<!--
<h3>Citations</h3>
<ol>
<li><a id="cite-1" href=""></a></li>
</ol>
-->
<hr>
<nav class="chapter-navigation">
<a class="previous-chapter" href="../5-typography">
<span class="number">5</span>
<span class="title">Typography</span>
</a>
</nav>
</div>
</div>
<script src="../../js/footer.js"></script>
</body>
</html>
================================================
FILE: chapters/_template.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ChapterName — Chapter # — Magic of CSS — Adam Schwartz</title>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<link rel="icon" href="/magic-of-css/favicon.ico">
<link rel="stylesheet" href="../../css/base.css">
<link rel="stylesheet" href="../../css/logo.css">
<link rel="stylesheet" href="../../css/chapter.css">
<script src="../../js/chapters.js"></script>
</head>
<body>
<div class="page">
<a class="logo" href="/../.."><h1 class="the-magic-of">The Magic of CSS</h1><div class="css-rainbow"><div class="css-letter css-rainbow-c"><div class="rainbow"><div class="bands"><div class="red"></div><div class="orange"></div><div class="yellow"></div><div class="green"></div><div class="blue"></div><div class="purple"></div></div></div></div><div class="css-letter css-rainbow-s css-rainbow-s-1"><div class="top-half"><div class="rainbow"><div class="bands"><div class="red"></div><div class="orange"></div><div class="yellow"></div><div class="green"></div><div class="blue"></div><div class="purple"></div></div></div></div><div class="bottom-half"><div class="rainbow"><div class="bands"><div class="purple"></div><div class="blue"></div><div class="green"></div><div class="yellow"></div><div class="orange"></div><div class="red"></div></div></div></div></div><div class="css-letter css-rainbow-s css-rainbow-s-2"><div class="top-half"><div class="rainbow"><div class="bands"><div class="red"></div><div class="orange"></div><div class="yellow"></div><div class="green"></div><div class="blue"></div><div class="purple"></div></div></div></div><div class="bottom-half"><div class="rainbow"><div class="bands"><div class="purple"></div><div class="blue"></div><div class="green"></div><div class="yellow"></div><div class="orange"></div><div class="red"></div></div></div></div></div></div></a>
<div class="chapter">
<h1>
<span class="number">Chapter #</span>
<span class="title">ChapterName</span>
</h1>
<hr>
<h3>Further reading</h3>
<ul>
<li><a href=""></a></li>
</ul>
<h3>Citations</h3>
<ol>
<li><a id="cite-1" href=""></a></li>
</ol>
<hr>
<nav class="chapter-navigation">
<a class="previous-chapter" href="../#-">
<span class="number">#</span>
<span class="title"></span>
</a>
<a class="next-chapter" href="../#-">
<span class="number">#</span>
<span class="title"></span>
</a>
</nav>
</div>
</div>
<script src="../../js/footer.js"></script>
</body>
</html>
================================================
FILE: chapters/preface/index.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Preface — Magic of CSS — Adam Schwartz</title>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<link rel="icon" href="/magic-of-css/favicon.ico">
<link rel="stylesheet" href="../../css/base.css">
<link rel="stylesheet" href="../../css/logo.css">
<link rel="stylesheet" href="../../css/chapter.css">
<script src="../../js/chapters.js"></script>
</head>
<body>
<div class="page">
<a class="logo" href="/../.."><h1 class="the-magic-of">The Magic of CSS</h1><div class="css-rainbow"><div class="css-letter css-rainbow-c"><div class="rainbow"><div class="bands"><div class="red"></div><div class="orange"></div><div class="yellow"></div><div class="green"></div><div class="blue"></div><div class="purple"></div></div></div></div><div class="css-letter css-rainbow-s css-rainbow-s-1"><div class="top-half"><div class="rainbow"><div class="bands"><div class="red"></div><div class="orange"></div><div class="yellow"></div><div class="green"></div><div class="blue"></div><div class="purple"></div></div></div></div><div class="bottom-half"><div class="rainbow"><div class="bands"><div class="purple"></div><div class="blue"></div><div class="green"></div><div class="yellow"></div><div class="orange"></div><div class="red"></div></div></div></div></div><div class="css-letter css-rainbow-s css-rainbow-s-2"><div class="top-half"><div class="rainbow"><div class="bands"><div class="red"></div><div class="orange"></div><div class="yellow"></div><div class="green"></div><div class="blue"></div><div class="purple"></div></div></div></div><div class="bottom-half"><div class="rainbow"><div class="bands"><div class="purple"></div><div class="blue"></div><div class="green"></div><div class="yellow"></div><div class="orange"></div><div class="red"></div></div></div></div></div></div></a>
<div class="chapter">
<h1>
<span class="title">Preface</span>
</h1>
<p>CSS is <a href="http://en.wikipedia.org/wiki/Comparison_of_layout_engines_%28Cascading_Style_Sheets%29">a mess</a>. We all love it, but it’s a mess. I liken it to English: there are a bunch of rules, and you can learn them. But sometimes you’re better off just trying shit and seeing what works and what doesn’t. <em>Magic</em> is a codification of what I’ve learned in that crazy process.</p>
<p>The material in this textbook is intermediate-to-advanced. It assumes an understanding of the <a href="http://www.w3schools.com/css/css_syntax.asp">CSS syntax</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Cascading_and_inheritance">cascading and inheritance</a>, and commonly used <a href="https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors">selectors</a>. It also assumes you’ve had enough experience with CSS to have learned not to make <a href="http://sixrevisions.com/css/12-common-css-mistakes-web-developers-make/">these common mistakes</a> anymore.</p>
<p>As always, <a href="https://github.com/adamschwartz/magic-of-css/issues">feedback</a> is welcome. I hope you enjoy reading <em>Magic</em>.</p>
<hr>
<nav class="chapter-navigation">
<a class="next-chapter" href="../1-the-box">
<span class="number">1</span>
<span class="title">The Box</span>
</a>
</nav>
</div>
</div>
<script src="../../js/footer.js"></script>
</body>
</html>
================================================
FILE: config.rb
================================================
css_dir = "css"
sass_dir = "sass"
output_style = :nested
relative_assets = true
line_comments = false
================================================
FILE: css/base.css
================================================
@font-face {
font-family: "social-icons";
src: url(data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAAcoABEAAAAACkgAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABgAAAABwAAAAcaf99jEdERUYAAAGcAAAAHQAAACAAPwAET1MvMgAAAbwAAABEAAAAVoI5TzhjbWFwAAACAAAAAFcAAAFqCtZoHmN2dCAAAAJYAAAAAgAAAAIAAAAAZnBnbQAAAlwAAAGxAAACZVO0L6dnYXNwAAAEEAAAAAgAAAAIAAAAEGdseWYAAAQYAAAApgAAAKgkgkHyaGVhZAAABMAAAAAvAAAANgR2todoaGVhAAAE8AAAAB0AAAAkDOUH3WhtdHgAAAUQAAAAMAAAAEgw7QAzbG9jYQAABUAAAAAOAAAAJgBUAAhtYXhwAAAFUAAAAB8AAAAgASsANG5hbWUAAAVwAAABGAAAAiou8lNRcG9zdAAABogAAABmAAAAvq8qqjRwcmVwAAAG8AAAAC4AAAAusPIrFHdlYmYAAAcgAAAABgAAAAaFeVLoAAAAAQAAAADMPaLPAAAAAM6zpMQAAAAAzw41+HjaY2BkYGDgA2IJBhBgYmAEQkEgZgHzGAAFBQBEAAAAeNpjYGTqZZzAwMrAwirEOouBgVEeQjNfZ0hhEmBgYGJgZWbACgLSXFMYHBQYXjCwnf13loGBdQWDGVCYESQHAI4oCjp42mNgYGBmgGAZBkYGEEgB8hjBfBYGDyDNx8DBwMTAxsCgwKWgrxCv+ucFw///IIUKDMj8B8z379/fcEtEQhBqDhJgBOqGCTIyAQkmdAUMwx4AABb9EFwAAAAAAHjaXVG7TltBEN0NDwOBxNggOdoUs5mQxnuhBQnE1Y1iZDuF5QhpN3KRi3EBH0CBRA3arxmgoaRImwYhF0h8Qj4hEjNriKI0Ozuzc86ZM0vKkap36WvPU+ckkMLdBs02/U5ItbMA96Tr642MtIMHWmxm9Mp1+/4LBpvRlDtqAOU9bykPGU07gVq0p/7R/AqG+/wf8zsYtDTT9NQ6CekhBOabcUuD7xnNussP+oLV4WIwMKSYpuIuP6ZS/rc052rLsLWR0byDMxH5yTRAU2ttBJr+1CHV83EUS5DLprE2mJiy/iQTwYXJdFVTtcz42sFdsrPoYIMqzYEH2MNWeQweDg8mFNK3JMosDRH2YqvECBGTHAo55dzJ/qRA+UgSxrxJSjvjhrUGxpHXwKA2T7P/PJtNbW8dwvhZHMF3vxlLOvjIhtoYEWI7YimACURCRlX5hhrPvSwG5FL7z0CUgOXxj3+dCLTu2EQ8l7V1DjFWCHp+29zyy4q7VrnOi0J3b6pqqNIpzftezr7HA54eC8NBY8Gbz/v+SoH6PCyuNGgOBEN6N3r/orXqiKu8Fz6yJ9O/sVoAAAAAAQAB//8AD3jaY2BkQAKGDAyMDMb/P7Fbs65g0GdgMBcTVzDXY1QXMzYCUraMYuJ6jCbmYiziaqYmZuZG4mbmbOwgLCrCxcjGoq5grG7IyHSyco+quryhYeMKvyifKONuxq6nXDenL8qtzdGszM7yyQnb8O3fiuP/Ts9gY5zH0l3IwiN9sp1Fm8V4wZGwVWe4tTVnXWUqlXRs9uTRzQ/Qn/bv1r+3Z5pZAPHvLrkAAHjaY2BkYGAA4nzrKy/i+W2+MnBzMIDAeT7THwj6/yd2a9YVQC4HAxNIFAA6SAsZAHjaY2BkYGBd8f8UAwMHAwiwWzMwMqACIQBP4wLVAAAAeNrjYIAAplVAfIWBgXUFgmZ8BMRZQMmPULwVyFcE0gEQGiTHAuSy5zAYAwBm0QlJeNpjYCAIOBhCAACSAF0AAHjaY2BkYGAQYjBgANEMDExAmolBjAHKZWAAAAgxAGEAeNp1kEFKw0AUhr+xVdCCuOp6VqKb2DYFxZUgKHQpUsFdWmubEmNIo6AnEE/gUTyCbjyCZ/HvZNpFgoSZfO9//3vzZoAW7zQwzW1grlWyYU9RyRvs8uq5If3NcxPLh+dN2nx63pLnx/MOQ349t9g3fc9ftM2t5286JuOcRzJeyImZMqNQ9wOph/r36NAlFI3ksHKWrpiUiERKxJMqZi6zUHymda8olTqRIxEHjLU/1PQr0VT1ibrktWw1thX/UNHyzNj5rOYMNG216lKUOmfk1Lv1XRY8q1tPaqGq5dS5m9JyUTs5c7m5lLH0wL1SIfWUI33/3fdGymidXU14rRtMFA00Uere+MTtobqFHGvvKlq9ff8PSxlTc3jabcVNCoMwFEXhd9Nqaq1WpAuJqfFnKII7ceCkgxJx+y28O/TA4RMj2kvOq/9DDAwuuCJBCosbMtyR44ECJZ6o7P7ZvHOONtTTN21poB3t6UBHOql+UYMaltnGY4tx/f4A6oAhoQAAuAH/hbABjQBLsAhQWLEBAY5ZsUYGK1ghsBBZS7AUUlghsIBZHbAGK1xYWbAUKwAAAAFS6IV4AAA=) format("woff");
font-weight: normal;
font-style: normal; }
*, *::after, *::before {
box-sizing: border-box; }
::-moz-selection {
text-shadow: none;
background: currentColor;
color: #fff; }
::selection {
text-shadow: none;
background: currentColor;
color: #fff; }
html {
font-size: 16px;
--purple: #6335e6;
--blue: #0085ae;
--green: #8ebd14;
--yellow: #ffc359;
--orange: #ff716a;
--red: #ff3283; }
@media (min-width: 72rem) {
html {
font-size: 20px; } }
body {
font-family: Avenir, "Helvetica Neue", sans-serif;
background: #fff;
color: #000;
margin: 0;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-webkit-text-size-adjust: 100%; }
h1, h2, h3, h4, h5, h6 {
font-weight: 600; }
a {
color: #0085ae; }
a:visited {
color: #6335e6; }
.clearfix {
*zoom: 1; }
.clearfix:after {
content: "";
display: table;
clear: both; }
================================================
FILE: css/chapter.css
================================================
@charset "UTF-8";
@font-face {
font-family: "social-icons";
src: url(data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAAcoABEAAAAACkgAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABgAAAABwAAAAcaf99jEdERUYAAAGcAAAAHQAAACAAPwAET1MvMgAAAbwAAABEAAAAVoI5TzhjbWFwAAACAAAAAFcAAAFqCtZoHmN2dCAAAAJYAAAAAgAAAAIAAAAAZnBnbQAAAlwAAAGxAAACZVO0L6dnYXNwAAAEEAAAAAgAAAAIAAAAEGdseWYAAAQYAAAApgAAAKgkgkHyaGVhZAAABMAAAAAvAAAANgR2todoaGVhAAAE8AAAAB0AAAAkDOUH3WhtdHgAAAUQAAAAMAAAAEgw7QAzbG9jYQAABUAAAAAOAAAAJgBUAAhtYXhwAAAFUAAAAB8AAAAgASsANG5hbWUAAAVwAAABGAAAAiou8lNRcG9zdAAABogAAABmAAAAvq8qqjRwcmVwAAAG8AAAAC4AAAAusPIrFHdlYmYAAAcgAAAABgAAAAaFeVLoAAAAAQAAAADMPaLPAAAAAM6zpMQAAAAAzw41+HjaY2BkYGDgA2IJBhBgYmAEQkEgZgHzGAAFBQBEAAAAeNpjYGTqZZzAwMrAwirEOouBgVEeQjNfZ0hhEmBgYGJgZWbACgLSXFMYHBQYXjCwnf13loGBdQWDGVCYESQHAI4oCjp42mNgYGBmgGAZBkYGEEgB8hjBfBYGDyDNx8DBwMTAxsCgwKWgrxCv+ucFw///IIUKDMj8B8z379/fcEtEQhBqDhJgBOqGCTIyAQkmdAUMwx4AABb9EFwAAAAAAHjaXVG7TltBEN0NDwOBxNggOdoUs5mQxnuhBQnE1Y1iZDuF5QhpN3KRi3EBH0CBRA3arxmgoaRImwYhF0h8Qj4hEjNriKI0Ozuzc86ZM0vKkap36WvPU+ckkMLdBs02/U5ItbMA96Tr642MtIMHWmxm9Mp1+/4LBpvRlDtqAOU9bykPGU07gVq0p/7R/AqG+/wf8zsYtDTT9NQ6CekhBOabcUuD7xnNussP+oLV4WIwMKSYpuIuP6ZS/rc052rLsLWR0byDMxH5yTRAU2ttBJr+1CHV83EUS5DLprE2mJiy/iQTwYXJdFVTtcz42sFdsrPoYIMqzYEH2MNWeQweDg8mFNK3JMosDRH2YqvECBGTHAo55dzJ/qRA+UgSxrxJSjvjhrUGxpHXwKA2T7P/PJtNbW8dwvhZHMF3vxlLOvjIhtoYEWI7YimACURCRlX5hhrPvSwG5FL7z0CUgOXxj3+dCLTu2EQ8l7V1DjFWCHp+29zyy4q7VrnOi0J3b6pqqNIpzftezr7HA54eC8NBY8Gbz/v+SoH6PCyuNGgOBEN6N3r/orXqiKu8Fz6yJ9O/sVoAAAAAAQAB//8AD3jaY2BkQAKGDAyMDMb/P7Fbs65g0GdgMBcTVzDXY1QXMzYCUraMYuJ6jCbmYiziaqYmZuZG4mbmbOwgLCrCxcjGoq5grG7IyHSyco+quryhYeMKvyifKONuxq6nXDenL8qtzdGszM7yyQnb8O3fiuP/Ts9gY5zH0l3IwiN9sp1Fm8V4wZGwVWe4tTVnXWUqlXRs9uTRzQ/Qn/bv1r+3Z5pZAPHvLrkAAHjaY2BkYGAA4nzrKy/i+W2+MnBzMIDAeT7THwj6/yd2a9YVQC4HAxNIFAA6SAsZAHjaY2BkYGBd8f8UAwMHAwiwWzMwMqACIQBP4wLVAAAAeNrjYIAAplVAfIWBgXUFgmZ8BMRZQMmPULwVyFcE0gEQGiTHAuSy5zAYAwBm0QlJeNpjYCAIOBhCAACSAF0AAHjaY2BkYGAQYjBgANEMDExAmolBjAHKZWAAAAgxAGEAeNp1kEFKw0AUhr+xVdCCuOp6VqKb2DYFxZUgKHQpUsFdWmubEmNIo6AnEE/gUTyCbjyCZ/HvZNpFgoSZfO9//3vzZoAW7zQwzW1grlWyYU9RyRvs8uq5If3NcxPLh+dN2nx63pLnx/MOQ349t9g3fc9ftM2t5286JuOcRzJeyImZMqNQ9wOph/r36NAlFI3ksHKWrpiUiERKxJMqZi6zUHymda8olTqRIxEHjLU/1PQr0VT1ibrktWw1thX/UNHyzNj5rOYMNG216lKUOmfk1Lv1XRY8q1tPaqGq5dS5m9JyUTs5c7m5lLH0wL1SIfWUI33/3fdGymidXU14rRtMFA00Uere+MTtobqFHGvvKlq9ff8PSxlTc3jabcVNCoMwFEXhd9Nqaq1WpAuJqfFnKII7ceCkgxJx+y28O/TA4RMj2kvOq/9DDAwuuCJBCosbMtyR44ECJZ6o7P7ZvHOONtTTN21poB3t6UBHOql+UYMaltnGY4tx/f4A6oAhoQAAuAH/hbABjQBLsAhQWLEBAY5ZsUYGK1ghsBBZS7AUUlghsIBZHbAGK1xYWbAUKwAAAAFS6IV4AAA=) format("woff");
font-weight: normal;
font-style: normal; }
body {
margin: 0; }
@media (min-width: 44rem) {
body {
margin: 0 0 8em; } }
h1 {
text-align: center;
line-height: normal; }
h1 .number {
display: block;
font-weight: 300;
text-transform: uppercase;
letter-spacing: 0.4em;
padding-left: 0.4em;
font-size: 0.55em;
line-height: 1;
position: relative;
margin-bottom: 0;
color: #aaa; }
h1 .title {
display: block;
font-weight: 100;
margin: 0.16667em 0 1em;
font-size: 1.5em; }
img {
max-width: 100%; }
sup {
vertical-align: baseline;
position: relative;
top: -0.5em;
font-size: 0.85em; }
.logo {
margin: 0 auto 5em auto; }
@media (min-width: 44rem) {
.logo {
margin: 0 auto 8em auto; } }
.page {
padding-top: 2em; }
@media (min-width: 44rem) {
.page {
padding-top: 8em; } }
.chapter {
width: 36rem;
max-width: 100%;
padding: 0 0.66667rem 1rem;
margin: 0 auto;
line-height: 1.5em; }
.chapter a {
color: inherit;
text-decoration: none;
background: linear-gradient(#ffffff, #ffffff), linear-gradient(#ffffff, #ffffff), linear-gradient(#333332, #333332);
background-size: 0.05em 1px, 0.05em 1px, 1px 1px;
background-repeat: no-repeat, no-repeat, repeat-x;
text-shadow: 0.03em 0 #fff, -0.03em 0 #fff, 0 0.03em #fff, 0 -0.03em #fff, 0.06em 0 #fff, -0.06em 0 #fff, 0.09em 0 #fff, -0.09em 0 #fff, 0.12em 0 #fff, -0.12em 0 #fff, 0.15em 0 #fff, -0.15em 0 #fff;
background-position-y: 87%, 87%, 87%;
background-position-x: 0%, 100%, 0%; }
.chapter a::selection {
text-shadow: 0.03em 0 currentColor, -0.03em 0 currentColor, 0 0.03em currentColor, 0 -0.03em currentColor, 0.06em 0 currentColor, -0.06em 0 currentColor, 0.09em 0 currentColor, -0.09em 0 currentColor, 0.12em 0 currentColor, -0.12em 0 currentColor, 0.15em 0 currentColor, -0.15em 0 currentColor;
background: currentColor; }
.chapter a::-moz-selection {
text-shadow: 0.03em 0 currentColor, -0.03em 0 currentColor, 0 0.03em currentColor, 0 -0.03em currentColor, 0.06em 0 currentColor, -0.06em 0 currentColor, 0.09em 0 currentColor, -0.09em 0 currentColor, 0.12em 0 currentColor, -0.12em 0 currentColor, 0.15em 0 currentColor, -0.15em 0 currentColor;
background: currentColor; }
.chapter a::before, .chapter a::after, .chapter a *::before, .chapter a *::after, .chapter a *:not(em) {
text-shadow: none; }
.chapter a:visited {
color: inherit; }
.chapter h2, .chapter h3, .chapter h4, .chapter h5, .chapter h6 {
line-height: 1.2em;
margin-top: 2rem;
margin-bottom: 0.125em; }
.chapter h2 + *, .chapter h3 + *, .chapter h4 + *, .chapter h5 + *, .chapter h6 + * {
margin-top: 0; }
.chapter sup a, .chapter .chapter-navigation a {
background-image: none;
text-shadow: none; }
.example {
max-width: 100%;
overflow: auto;
-webkit-overflow-scrolling: touch; }
.example.side-by-side {
*zoom: 1; }
.example.side-by-side:after {
content: "";
display: table;
clear: both; }
.example.side-by-side .left {
float: left;
width: 50%; }
.example.side-by-side .right {
float: right;
width: 50%; }
.example.side-by-side .left > p:first-child, .example.side-by-side .right > p:first-child {
margin-top: 0; }
.example > p:first-child {
margin-top: 0; }
.example > p:last-child {
margin-bottom: 0; }
@media (min-width: 92.66667rem) {
.example-wrapper {
*zoom: 1;
width: 71.33334rem;
margin-left: -18.33333rem;
margin-top: 1em;
margin-bottom: 2em;
transition: opacity 0.4s; }
.example-wrapper:after {
content: "";
display: table;
clear: both; }
.example-wrapper style[contenteditable], .example-wrapper pre, .example-wrapper .example {
width: 34.66667rem;
margin-top: 0; }
.example-wrapper pre, .example-wrapper style[contenteditable] {
float: left; }
.example-wrapper .example {
float: right;
overflow: visible; }
.example-wrapper.typography-example-wrapper {
margin-bottom: 4em; }
.example-wrapper.typography-example-wrapper .example {
overflow: hidden; }
body.contextual-open .example-wrapper {
opacity: 0; } }
style[contenteditable] {
margin: 1em 0;
display: block; }
code, pre, style[contenteditable] {
font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace; }
pre, style[contenteditable] {
background-color: #eee;
color: #333;
padding: 0.5em 0.66667em;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
font-size: 0.8em;
line-height: 1.71em;
white-space: pre;
word-wrap: normal; }
style[contenteditable] {
-moz-transition: box-shadow 0.2s;
-o-transition: box-shadow 0.2s;
-webkit-transition: box-shadow 0.2s;
transition: box-shadow 0.2s;
-moz-box-shadow: 0 0 #ccc;
-webkit-box-shadow: 0 0 #ccc;
box-shadow: 0 0 #ccc;
padding: 0.66667em 1em; }
style[contenteditable]:focus {
-moz-box-shadow: -0.5em 0 #ccc;
-webkit-box-shadow: -0.5em 0 #ccc;
box-shadow: -0.5em 0 #ccc;
outline: none; }
code {
font-size: 0.8em;
padding: 0.15625em 0.3125em;
background: #eee;
white-space: nowrap;
font-style: normal; }
@media (min-width: 44rem) {
code {
padding: 3px 6px; } }
pre > code {
font-size: inherit;
background: transparent;
padding: 0;
white-space: inherit; }
hr {
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIgc3RvcC1vcGFjaXR5PSIwLjEiLz48c3RvcCBvZmZzZXQ9IjkwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIgc3RvcC1vcGFjaXR5PSIwLjEiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMwMDAwMDAiIHN0b3Atb3BhY2l0eT0iMC4wIi8+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0idXJsKCNncmFkKSIgLz48L3N2Zz4g');
background-size: 100%;
background-image: -webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(0, 0, 0, 0)), color-stop(10%, rgba(0, 0, 0, 0.1)), color-stop(90%, rgba(0, 0, 0, 0.1)), color-stop(100%, rgba(0, 0, 0, 0)));
background-image: -moz-linear-gradient(left, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.1) 10%, rgba(0, 0, 0, 0.1) 90%, rgba(0, 0, 0, 0));
background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.1) 10%, rgba(0, 0, 0, 0.1) 90%, rgba(0, 0, 0, 0));
background-image: linear-gradient(to right, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.1) 10%, rgba(0, 0, 0, 0.1) 90%, rgba(0, 0, 0, 0));
height: 1px;
width: 100%;
border: 0;
margin: 2em auto; }
nav.chapter-navigation {
position: relative;
height: 2.5em;
max-width: 100%;
overflow: hidden; }
nav.chapter-navigation a {
box-sizing: border-box;
display: inline-block;
vertical-align: middle;
*vertical-align: auto;
*zoom: 1;
*display: inline;
position: absolute;
padding: 0.43em 0.94em;
line-height: 1.7em;
background: #eee;
border: 0;
height: 100%;
text-decoration: none; }
nav.chapter-navigation a, nav.chapter-navigation a:visited {
color: inherit; }
nav.chapter-navigation a .title {
display: none; }
nav.chapter-navigation a .title.preface-title {
display: inline; }
nav.chapter-navigation a .number::before {
content: "Chapter "; }
@media (min-width: 44rem) {
nav.chapter-navigation a .title {
display: inline; }
nav.chapter-navigation a .number::after {
content: ": "; } }
nav.chapter-navigation a::after {
content: "";
position: absolute;
background: transparent;
height: 0;
width: 0;
border: 1.25em solid;
top: 0; }
nav.chapter-navigation a.previous-chapter {
left: 1.25em; }
nav.chapter-navigation a.previous-chapter::after {
right: 99.9%;
border-color: transparent #eee transparent transparent; }
nav.chapter-navigation a.next-chapter {
right: 1.25em; }
nav.chapter-navigation a.next-chapter::after {
left: 99.9%;
border-color: transparent transparent transparent #eee; }
@media (max-width: 72rem) {
nav.chapter-navigation-fullpage {
display: none; } }
nav.chapter-navigation-fullpage a {
box-sizing: content-box;
position: fixed;
-webkit-transform: translate3d(0, 0, 0);
top: 0;
height: 100%;
width: 4rem;
background-image: linear-gradient(#ff3283, #6335e6);
background-size: 1rem 100%;
background-repeat: no-repeat;
color: inherit;
text-decoration: none;
transition: background-position 0.4s; }
nav.chapter-navigation-fullpage a .title {
position: absolute;
top: 0;
bottom: 0;
height: 2em;
line-height: 2em;
margin: auto;
opacity: 0;
pointer-events: none;
white-space: nowrap; }
nav.chapter-navigation-fullpage a:hover .title {
opacity: 1; }
nav.chapter-navigation-fullpage a::before {
content: "";
position: absolute;
top: 0;
bottom: 0;
margin: auto;
height: 1em;
width: 1em;
border: 1px solid;
opacity: 0;
transform: rotateZ(45deg); }
nav.chapter-navigation-fullpage a:hover::before {
opacity: 1; }
nav.chapter-navigation-fullpage .previous-chapter {
left: 0;
background-position: -1rem top; }
nav.chapter-navigation-fullpage .previous-chapter::before {
left: 1rem;
border-right: 0;
border-top: 0;
transition: opacity 0.4s, left 0.4s; }
nav.chapter-navigation-fullpage .previous-chapter .title {
left: 1rem;
transition: opacity 0.4s, left 0.4s; }
nav.chapter-navigation-fullpage .previous-chapter:hover {
background-position: left top; }
nav.chapter-navigation-fullpage .previous-chapter:hover::before {
left: 1.75rem; }
nav.chapter-navigation-fullpage .previous-chapter:hover .title {
left: 3rem; }
nav.chapter-navigation-fullpage .next-chapter {
right: 0;
background-position: 5rem top; }
nav.chapter-navigation-fullpage .next-chapter::before {
right: 1rem;
border-left: 0;
border-bottom: 0;
transition: opacity 0.4s, right 0.4s; }
nav.chapter-navigation-fullpage .next-chapter .title {
right: 1rem;
transition: opacity 0.4s, right 0.4s; }
nav.chapter-navigation-fullpage .next-chapter:hover {
background-position: right top; }
nav.chapter-navigation-fullpage .next-chapter:hover::before {
right: 1.75rem; }
nav.chapter-navigation-fullpage .next-chapter:hover .title {
right: 3rem; }
h3.magic {
position: relative; }
h3.magic::before {
display: block; }
@media (min-width: 38rem) {
h3.magic::before {
-moz-box-shadow: 0 -1.25em #0085ae, 0 -1.875em #8ebd14, 0 -2.5em #ffc359, 0 -3.125em #ff716a, 0 -3.75em #ff3283;
-webkit-box-shadow: 0 -1.25em #0085ae, 0 -1.875em #8ebd14, 0 -2.5em #ffc359, 0 -3.125em #ff716a, 0 -3.75em #ff3283;
box-shadow: 0 -1.25em #0085ae, 0 -1.875em #8ebd14, 0 -2.5em #ffc359, 0 -3.125em #ff716a, 0 -3.75em #ff3283;
-moz-border-radius: 50%;
-webkit-border-radius: 50%;
border-radius: 50%;
position: absolute;
content: "";
font-size: 1rem;
height: 0.9375em;
width: 0.9375em;
right: 100%;
margin: auto;
margin-right: 1.25em;
margin-top: 3.75em;
top: 0;
bottom: 0; }
h3.magic::after {
transform: rotateZ(-90deg);
position: absolute;
content: "Magic";
text-transform: uppercase;
letter-spacing: 0.4em;
font-size: 0.625rem;
right: 100%;
color: #fff;
margin-top: 1.25rem;
margin-right: 0.0625rem;
line-height: 1.25em; } }
@media (max-width: 38rem) {
h3.magic::before {
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzYzMzVlNiIvPjxzdG9wIG9mZnNldD0iMTIuNSUiIHN0b3AtY29sb3I9IiNmZjMyODMiLz48c3RvcCBvZmZzZXQ9IjI1JSIgc3RvcC1jb2xvcj0iI2ZmNzE2YSIgc3RvcC1vcGFjaXR5PSIwLjgiLz48c3RvcCBvZmZzZXQ9IjM3LjUlIiBzdG9wLWNvbG9yPSIjZmZjMzU5IiBzdG9wLW9wYWNpdHk9IjAuNiIvPjxzdG9wIG9mZnNldD0iNTAlIiBzdG9wLWNvbG9yPSIjOGViZDE0IiBzdG9wLW9wYWNpdHk9IjAuNCIvPjxzdG9wIG9mZnNldD0iNjIuNSUiIHN0b3AtY29sb3I9IiMwMDg1YWUiIHN0b3Atb3BhY2l0eT0iMC4yIi8+PHN0b3Agb2Zmc2V0PSI3NSUiIHN0b3AtY29sb3I9IiM2MzM1ZTYiIHN0b3Atb3BhY2l0eT0iMC4wIi8+PHN0b3Agb2Zmc2V0PSI4Ny41JSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMwMDAwMDAiIHN0b3Atb3BhY2l0eT0iMC4wIi8+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0idXJsKCNncmFkKSIgLz48L3N2Zz4g');
background-size: 100%;
background-image: -webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, #6335e6), color-stop(12.5%, #ff3283), color-stop(25%, rgba(255, 113, 106, 0.8)), color-stop(37.5%, rgba(255, 195, 89, 0.6)), color-stop(50%, rgba(142, 189, 20, 0.4)), color-stop(62.5%, rgba(0, 133, 174, 0.2)), color-stop(75%, rgba(99, 53, 230, 0)), color-stop(87.5%, rgba(0, 0, 0, 0)), color-stop(100%, rgba(0, 0, 0, 0)));
background-image: -moz-linear-gradient(left, #6335e6, #ff3283, rgba(255, 113, 106, 0.8), rgba(255, 195, 89, 0.6), rgba(142, 189, 20, 0.4), rgba(0, 133, 174, 0.2), rgba(99, 53, 230, 0), rgba(0, 0, 0, 0), rgba(0, 0, 0, 0));
background-image: -webkit-linear-gradient(left, #6335e6, #ff3283, rgba(255, 113, 106, 0.8), rgba(255, 195, 89, 0.6), rgba(142, 189, 20, 0.4), rgba(0, 133, 174, 0.2), rgba(99, 53, 230, 0), rgba(0, 0, 0, 0), rgba(0, 0, 0, 0));
background-image: linear-gradient(to right, #6335e6, #ff3283, rgba(255, 113, 106, 0.8), rgba(255, 195, 89, 0.6), rgba(142, 189, 20, 0.4), rgba(0, 133, 174, 0.2), rgba(99, 53, 230, 0), rgba(0, 0, 0, 0), rgba(0, 0, 0, 0));
-moz-border-radius: 0;
-webkit-border-radius: 0;
border-radius: 0;
-moz-box-shadow: none;
-webkit-box-shadow: none;
box-shadow: none;
content: "Magic";
position: static;
height: auto;
width: auto;
text-transform: uppercase;
letter-spacing: 0.4em;
font-size: 0.625rem;
color: #fff;
margin: 1rem -0.66667rem;
padding: 0.1rem 0.66667rem; }
h3.magic::after {
display: none; } }
dl {
*zoom: 1;
margin: 1.5em auto; }
dl:after {
content: "";
display: table;
clear: both; }
dl dt {
display: inline-block;
vertical-align: middle;
*vertical-align: auto;
*zoom: 1;
*display: inline;
line-height: 2em;
border-left: 0.25em solid; }
dl dt:nth-of-type(5n + 1) {
border-left-color: #ff3283; }
dl dt:nth-of-type(5n + 2) {
border-left-color: #ff716a; }
dl dt:nth-of-type(5n + 3) {
border-left-color: #ffc359; }
dl dt:nth-of-type(5n + 4) {
border-left-color: #8ebd14; }
dl dt:nth-of-type(5n + 5) {
border-left-color: #0085ae; }
dl dt:nth-of-type(5n + 6) {
border-left-color: #6335e6; }
@media (min-width: 44rem) {
dl dt, dl dd {
float: left; }
dl dt {
width: 30%;
padding-right: 5%;
clear: left; }
dl dd {
width: 70%;
margin: 0 0 1.5em; }
dl dd:last-child {
margin-bottom: 0; } }
em > em {
font-style: normal; }
figure {
position: relative;
margin: 1em 0;
text-align: center; }
figure img {
margin: 0 auto;
display: block; }
figure figcaption {
padding-top: 1em;
color: #888;
font-weight: 300;
letter-spacing: 0.03em; }
@media (min-width: 36rem) {
figure figcaption {
position: relative;
margin-top: 1em;
margin-left: 40%;
text-align: right; }
figure figcaption::after {
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIgc3RvcC1vcGFjaXR5PSIwLjEiLz48c3RvcCBvZmZzZXQ9IjkwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIgc3RvcC1vcGFjaXR5PSIwLjEiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');
background-size: 100%;
background-image: -webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, rgba(0, 0, 0, 0)), color-stop(10%, rgba(0, 0, 0, 0.1)), color-stop(90%, rgba(0, 0, 0, 0.1)));
background-image: -moz-linear-gradient(left, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.1) 10%, rgba(0, 0, 0, 0.1) 90%);
background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.1) 10%, rgba(0, 0, 0, 0.1) 90%);
background-image: linear-gradient(to right, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.1) 10%, rgba(0, 0, 0, 0.1) 90%);
content: "";
position: absolute;
top: 0;
right: 0;
left: 0;
height: 1px; } }
@media (min-width: 92.66667rem) {
figure figcaption {
position: absolute;
right: 100%;
top: 0;
bottom: 0;
padding: 0;
width: 20em;
display: -webkit-box;
display: -webkit-flex;
display: -moz-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-webkit-align-items: center;
-moz-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: flex-end;
-webkit-justify-content: flex-end;
-moz-box-pack: flex-end;
-ms-flex-pack: flex-end;
justify-content: flex-end; }
figure figcaption::after {
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuNSIgeTE9IjAuMCIgeDI9IjAuNSIgeTI9IjEuMCI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIgc3RvcC1vcGFjaXR5PSIwLjEiLz48c3RvcCBvZmZzZXQ9IjkwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIgc3RvcC1vcGFjaXR5PSIwLjEiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMwMDAwMDAiIHN0b3Atb3BhY2l0eT0iMC4wIi8+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0idXJsKCNncmFkKSIgLz48L3N2Zz4g');
background-size: 100%;
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, rgba(0, 0, 0, 0)), color-stop(10%, rgba(0, 0, 0, 0.1)), color-stop(90%, rgba(0, 0, 0, 0.1)), color-stop(100%, rgba(0, 0, 0, 0)));
background-image: -moz-linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.1) 10%, rgba(0, 0, 0, 0.1) 90%, rgba(0, 0, 0, 0));
background-image: -webkit-linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.1) 10%, rgba(0, 0, 0, 0.1) 90%, rgba(0, 0, 0, 0));
background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.1) 10%, rgba(0, 0, 0, 0.1) 90%, rgba(0, 0, 0, 0));
content: "";
position: absolute;
top: 20%;
bottom: 20%;
right: 1.875em;
width: 1px;
height: auto;
left: auto; }
figure figcaption .figcaption {
text-align: right;
padding-right: 3.75em; } }
figure.cushy {
margin-top: 2em;
margin-bottom: 2em; }
@media (min-width: 44rem) {
figure.cushy {
margin-top: 8em;
margin-bottom: 8em; } }
.magic-color {
min-height: 4em;
border-radius: 0.1875em;
margin: 0 0 1em; }
@media (min-width: 44rem) {
.magic-color {
margin: 4em -4em; } }
@media (min-width: 72rem) {
.magic-color {
margin: 4em -8em; } }
.magic-color h2 {
padding: 1em 0;
text-align: center;
color: #fff;
font-weight: 300;
text-transform: uppercase;
letter-spacing: 0.4em;
margin-left: 0.4em; }
.magic-color.red-gradient {
background-image: linear-gradient(135deg, #723362, #9d223c);
background-color: #9d223c; }
.magic-color.green-gradient {
background-image: linear-gradient(135deg, #5fa4ee, #56e7ca);
background-color: #5fa4ee; }
code + code.color {
position: relative;
border-radius: 0 0.1875em 0.1875em 0; }
code + code.color::after {
content: " "; }
code + code.color::before {
content: "";
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: #fff;
background-image: linear-gradient(45deg, #cccccc 25%, rgba(0, 0, 0, 0) 25%, rgba(0, 0, 0, 0) 75%, #cccccc 75%, #cccccc), linear-gradient(45deg, #cccccc 25%, rgba(0, 0, 0, 0) 25%, rgba(0, 0, 0, 0) 75%, #cccccc 75%, #cccccc);
background-size: 0.625rem 0.625rem;
border-radius: 0 0.1875rem 0.1875rem 0;
background-position: 0 0, 0.3125rem 0.3125rem; }
code + code.color > span {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
border-radius: 0 0.1875rem 0.1875rem 0; }
.contextual-display-wrapper {
position: absolute;
top: 0;
left: 0;
right: 0;
pointer-events: none;
overflow: hidden;
z-index: 25;
background: rgba(255, 255, 255, 0.6);
opacity: 0;
transition: opacity 0.4s;
-webkit-transform: translate3d(0, 0, 0); }
@media (min-width: 44rem) {
.contextual-display-wrapper {
position: fixed;
left: -100%;
right: -100%; } }
body.contextual-open .contextual-display-wrapper {
opacity: 1; }
.contextual-display {
position: absolute;
padding: 0 0.66667rem;
width: 36rem;
max-width: 100%;
left: 0;
right: 0;
margin: auto;
background: #fff;
padding-top: 1rem;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
margin-top: 2rem; }
body.contextual-open .contextual-display {
pointer-events: initial; }
@media (min-width: 44rem) {
.contextual-display {
padding-top: 0;
box-shadow: none;
margin-top: 0;
width: 18rem;
left: 54rem;
padding-left: 3.75em; }
.contextual-display::before {
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuNSIgeTE9IjAuMCIgeDI9IjAuNSIgeTI9IjEuMCI+PHN0b3Agb2Zmc2V0PSIxMCUiIHN0b3AtY29sb3I9IiMwMDAwMDAiIHN0b3Atb3BhY2l0eT0iMC4xIi8+PHN0b3Agb2Zmc2V0PSI5MCUiIHN0b3AtY29sb3I9IiMwMDAwMDAiIHN0b3Atb3BhY2l0eT0iMC4xIi8+PHN0b3Agb2Zmc2V0PSIxMDAlIiBzdG9wLWNvbG9yPSIjMDAwMDAwIiBzdG9wLW9wYWNpdHk9IjAuMCIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');
background-size: 100%;
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(10%, rgba(0, 0, 0, 0.1)), color-stop(90%, rgba(0, 0, 0, 0.1)), color-stop(100%, rgba(0, 0, 0, 0)));
background-image: -moz-linear-gradient(top, rgba(0, 0, 0, 0.1) 10%, rgba(0, 0, 0, 0.1) 90%, rgba(0, 0, 0, 0));
background-image: -webkit-linear-gradient(top, rgba(0, 0, 0, 0.1) 10%, rgba(0, 0, 0, 0.1) 90%, rgba(0, 0, 0, 0));
background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.1) 10%, rgba(0, 0, 0, 0.1) 90%, rgba(0, 0, 0, 0));
content: "";
position: absolute;
top: 0;
bottom: 20%;
left: 1.875em;
width: 1px; } }
.contextual-display a[data-contextual-close] {
-webkit-tap-highlight-color: transparent;
position: absolute;
top: 1rem;
right: 0.6666rem;
color: inherit;
cursor: pointer; }
@media (min-width: 44rem) {
.contextual-display a[data-contextual-close] {
top: 0;
right: 0; } }
.contextual-display a[data-contextual-close]::before {
content: "×";
position: absolute;
top: -0.15em;
right: 0;
width: 1em;
text-align: center;
line-height: 1.12em;
overflow: hidden;
height: 1em;
border-radius: 4px;
font-size: 1.75em; }
.contextual-display a[data-contextual-close]:hover::before {
background: #eee; }
.contextual-display > *:first-child {
margin-top: 0; }
.contextual-display > *:last-child {
margin-bottom: 0; }
.page {
transition: -webkit-transform 0.4s;
-webkit-transform: translate3d(0, 0, 0); }
@media (min-width: 44rem) {
body.contextual-open .page {
-webkit-transform: translate3d(-18rem, 0, 0); } }
.contextual-description {
margin-bottom: 1em; }
.contextual-example {
border-top: 0.0625em solid #eee;
padding: 2em 0;
text-align: center; }
.contextual-example .box {
display: inline-block;
vertical-align: middle;
*vertical-align: auto;
*zoom: 1;
*display: inline;
text-align: left;
min-width: 4em;
min-height: 4em;
background: #888;
margin-bottom: 2em; }
.contextual-example .box.light {
background: #eee; }
.contextual-example .text-box {
box-shadow: inset 0 0 0 0.1em #888;
padding: 0.5em 1em;
text-align: left;
margin-bottom: 1em; }
.contextual-example .text {
display: inline-block;
vertical-align: middle;
*vertical-align: auto;
*zoom: 1;
*display: inline; }
code.contextual-code-example {
cursor: pointer;
position: relative; }
code.contextual-code-example:hover, code.contextual-code-example.contextual-open-tree {
background: #e0e0e0;
z-index: 50; }
code.contextual-code-example:hover::after, code.contextual-code-example.contextual-open-tree::after {
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzYzMzVlNiIvPjxzdG9wIG9mZnNldD0iMTYuNjY2NjclIiBzdG9wLWNvbG9yPSIjZmYzMjgzIi8+PHN0b3Agb2Zmc2V0PSIzMy4zMzMzMyUiIHN0b3AtY29sb3I9IiNmZjcxNmEiLz48c3RvcCBvZmZzZXQ9IjUwJSIgc3RvcC1jb2xvcj0iI2ZmYzM1OSIvPjxzdG9wIG9mZnNldD0iNjYuNjY2NjclIiBzdG9wLWNvbG9yPSIjOGViZDE0Ii8+PHN0b3Agb2Zmc2V0PSI4My4zMzMzMyUiIHN0b3AtY29sb3I9IiMwMDg1YWUiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiM2MzM1ZTYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');
background-size: 100%;
background-image: -webkit-gradient(linear, 0% 50%, 100% 50%, color-stop(0%, #6335e6), color-stop(16.66667%, #ff3283), color-stop(33.33333%, #ff716a), color-stop(50%, #ffc359), color-stop(66.66667%, #8ebd14), color-stop(83.33333%, #0085ae), color-stop(100%, #6335e6));
background-image: -moz-linear-gradient(left, #6335e6, #ff3283, #ff716a, #ffc359, #8ebd14, #0085ae, #6335e6);
background-image: -webkit-linear-gradient(left, #6335e6, #ff3283, #ff716a, #ffc359, #8ebd14, #0085ae, #6335e6);
background-image: linear-gradient(to right, #6335e6, #ff3283, #ff716a, #ffc359, #8ebd14, #0085ae, #6335e6);
content: "";
position: absolute;
left: 0;
right: 0;
top: 0;
height: 1px; }
@media (min-width: 44rem) {
body.contextual-open .contextual-open-tree-parent {
position: relative;
z-index: 50; } }
.meta {
margin: 1em 0;
background: rgba(99, 53, 230, 0.05);
padding: 1em;
border-left: 0.2em solid #6335e6; }
.meta > *:first-child {
margin-top: 0; }
.meta > *:last-child {
margin-bottom: 0; }
.meta code {
background: rgba(99, 53, 230, 0.15); }
.meta code.contextual-code-example:hover, .meta code.contextual-code-example.contextual-open-tree {
background: rgba(99, 53, 230, 0.21); }
header.social {
position: absolute;
z-index: 3;
-webkit-transform: translate3d(0, 0, 0);
margin: auto;
top: 0;
left: 0;
right: 0;
height: 4em; }
@media (max-width: 44rem) {
header.social {
display: none; } }
header.social a.github {
position: absolute;
top: 0;
left: 0;
margin: 0;
padding: 2em;
opacity: 0.5; }
header.social a.github, header.social a.github:visited {
color: #777;
text-decoration: none; }
header.social a.github:hover, header.social a.github:visited:hover {
color: #6335e6; }
header.social a.twitter {
position: absolute;
display: block;
height: 3.5em;
width: 11.5em;
top: 0;
right: 0;
text-decoration: none;
opacity: 0.5;
background: none;
text-shadow: none; }
header.social a.twitter, header.social a.twitter:visited {
color: #777;
text-decoration: none; }
header.social a.twitter:hover, header.social a.twitter:visited:hover {
color: #0085ae; }
header.social a.twitter::before {
position: absolute;
top: 2em;
right: 3.4em;
content: "@adamfschwartz";
opacity: 0; }
header.social a.twitter:hover::before {
opacity: 1; }
header.social a.twitter::after {
position: absolute;
top: 2em;
right: 2em;
font-family: "social-icons";
content: "";
line-height: 1.4em; }
.eager {
display: block;
text-align: center;
padding-left: 1em;
padding-right: 1em; }
.eager .eager-outer {
-moz-border-radius: 0.3125em;
-webkit-border-radius: 0.3125em;
border-radius: 0.3125em;
padding: 4px;
background-color: #ff3283;
background-image: linear-gradient(90deg, #ff3283 0%, #ff3283 17%, #ff716a 17%, #ff716a 34%, #ffc359 34%, #ffc359 51%, #8ebd14 51%, #8ebd14 67%, #0085ae 67%, #0085ae 83%, #6335e6 83%, #6335e6 100%);
display: inline-block;
max-width: 100%;
width: 26em; }
.eager .eager-inner {
-moz-border-radius: 0.1875em;
-webkit-border-radius: 0.1875em;
border-radius: 0.1875em;
background-color: #fff;
background: linear-gradient(rgba(255, 255, 255, 0.91), #ffffff);
padding: 1.125em; }
.eager .smart-underlined {
color: inherit;
text-decoration: none;
background: linear-gradient(#ffffff, #ffffff), linear-gradient(#ffffff, #ffffff), linear-gradient(#333332, #333332);
background-size: 0.05em 1px, 0.05em 1px, 1px 1px;
background-repeat: no-repeat, no-repeat, repeat-x;
text-shadow: 0.03em 0 #fff, -0.03em 0 #fff, 0 0.03em #fff, 0 -0.03em #fff, 0.06em 0 #fff, -0.06em 0 #fff, 0.09em 0 #fff, -0.09em 0 #fff, 0.12em 0 #fff, -0.12em 0 #fff, 0.15em 0 #fff, -0.15em 0 #fff;
background-position-y: 87%, 87%, 87%;
background-position-x: 0%, 100%, 0%; }
.eager .smart-underlined::selection {
text-shadow: 0.03em 0 currentColor, -0.03em 0 currentColor, 0 0.03em currentColor, 0 -0.03em currentColor, 0.06em 0 currentColor, -0.06em 0 currentColor, 0.09em 0 currentColor, -0.09em 0 currentColor, 0.12em 0 currentColor, -0.12em 0 currentColor, 0.15em 0 currentColor, -0.15em 0 currentColor;
background: currentColor; }
.eager .smart-underlined::-moz-selection {
text-shadow: 0.03em 0 currentColor, -0.03em 0 currentColor, 0 0.03em currentColor, 0 -0.03em currentColor, 0.06em 0 currentColor, -0.06em 0 currentColor, 0.09em 0 currentColor, -0.09em 0 currentColor, 0.12em 0 currentColor, -0.12em 0 currentColor, 0.15em 0 currentColor, -0.15em 0 currentColor;
background: currentColor; }
.eager h1 {
font-size: 1em;
margin: 0 0 1em; }
.eager p {
margin: 1em 0 0; }
.eager p.small {
font-size: 0.8em;
padding: 0 2em;
line-height: 1.33em;
margin-bottom: -0.2em; }
.eager a.eager-button {
text-decoration: none;
display: block;
cursor: pointer;
-moz-border-radius: 10em;
-webkit-border-radius: 10em;
border-radius: 10em;
font-weight: bold;
padding: 0.7em 1.2em;
background: #4039a5;
color: #fff; }
.eager {
margin-top: 1em;
margin-bottom: 1em; }
@media (min-width: 44rem) {
.eager {
margin-top: 4em; } }
================================================
FILE: css/eager.css
================================================
.eager {
display: block;
text-align: center;
padding-left: 1em;
padding-right: 1em; }
.eager .eager-outer {
-moz-border-radius: 0.3125em;
-webkit-border-radius: 0.3125em;
border-radius: 0.3125em;
padding: 4px;
background-color: #ff3283;
background-image: linear-gradient(90deg, #ff3283 0%, #ff3283 17%, #ff716a 17%, #ff716a 34%, #ffc359 34%, #ffc359 51%, #8ebd14 51%, #8ebd14 67%, #0085ae 67%, #0085ae 83%, #6335e6 83%, #6335e6 100%);
display: inline-block;
max-width: 100%;
width: 26em; }
.eager .eager-inner {
-moz-border-radius: 0.1875em;
-webkit-border-radius: 0.1875em;
border-radius: 0.1875em;
background-color: #fff;
background: linear-gradient(rgba(255, 255, 255, 0.91), #ffffff);
padding: 1.125em; }
.eager .smart-underlined {
color: inherit;
text-decoration: none;
background: linear-gradient(#ffffff, #ffffff), linear-gradient(#ffffff, #ffffff), linear-gradient(#333332, #333332);
background-size: 0.05em 1px, 0.05em 1px, 1px 1px;
background-repeat: no-repeat, no-repeat, repeat-x;
text-shadow: 0.03em 0 #fff, -0.03em 0 #fff, 0 0.03em #fff, 0 -0.03em #fff, 0.06em 0 #fff, -0.06em 0 #fff, 0.09em 0 #fff, -0.09em 0 #fff, 0.12em 0 #fff, -0.12em 0 #fff, 0.15em 0 #fff, -0.15em 0 #fff;
background-position-y: 87%, 87%, 87%;
background-position-x: 0%, 100%, 0%; }
.eager .smart-underlined::selection {
text-shadow: 0.03em 0 currentColor, -0.03em 0 currentColor, 0 0.03em currentColor, 0 -0.03em currentColor, 0.06em 0 currentColor, -0.06em 0 currentColor, 0.09em 0 currentColor, -0.09em 0 currentColor, 0.12em 0 currentColor, -0.12em 0 currentColor, 0.15em 0 currentColor, -0.15em 0 currentColor;
background: currentColor; }
.eager .smart-underlined::-moz-selection {
text-shadow: 0.03em 0 currentColor, -0.03em 0 currentColor, 0 0.03em currentColor, 0 -0.03em currentColor, 0.06em 0 currentColor, -0.06em 0 currentColor, 0.09em 0 currentColor, -0.09em 0 currentColor, 0.12em 0 currentColor, -0.12em 0 currentColor, 0.15em 0 currentColor, -0.15em 0 currentColor;
background: currentColor; }
.eager h1 {
font-size: 1em;
margin: 0 0 1em; }
.eager p {
margin: 1em 0 0; }
.eager p.small {
font-size: 0.8em;
padding: 0 2em;
line-height: 1.33em;
margin-bottom: -0.2em; }
.eager a.eager-button {
text-decoration: none;
display: block;
cursor: pointer;
-moz-border-radius: 10em;
-webkit-border-radius: 10em;
border-radius: 10em;
font-weight: bold;
padding: 0.7em 1.2em;
background: #4039a5;
color: #fff; }
================================================
FILE: css/home.css
================================================
body {
margin: 0; }
@media (min-width: 44rem) {
body {
margin: 8em 0; } }
.page {
text-align: center;
padding: 2em 0; }
@media (min-width: 44rem) {
.page {
padding: 0; } }
.separator {
height: 2.5em; }
@media (min-width: 44rem) {
.separator {
height: 10em; } }
p.author {
font-size: 1.4rem;
margin-top: 2em;
letter-spacing: 0.05em;
padding-left: 0.43em;
color: #888;
font-weight: 300; }
p.author a {
text-decoration: none;
color: inherit; }
.share {
margin-top: -0.7rem;
margin-bottom: 0.7rem;
padding-left: 0.6rem;
font-size: 0; }
.share iframe {
display: inline-block;
vertical-align: middle;
background: #eee;
border-radius: 5px;
margin-left: auto;
margin-right: auto;
border: 0;
height: 2.4rem;
width: 13.6rem;
height: 1.6rem;
opacity: 0.8; }
.share iframe:hover {
opacity: 1; }
.share iframe.github {
width: 8rem; }
h2 {
font-weight: 300;
text-transform: uppercase;
letter-spacing: 0.4em;
font-size: 1.375em;
line-height: 1;
position: relative;
margin: 2.5rem 0;
color: #aaa;
padding: 0 1rem; }
h2 span {
margin-right: -0.4em; }
@media (min-width: 44rem) {
h2 {
margin: 5rem 0; } }
ol.chapters {
list-style-type: none;
margin-left: 0; }
ol.chapters > li {
clear: left;
counter-increment: chaptersCounter; }
ol.chapters > li:after {
content: "";
display: table;
clear: both; }
ol.chapters > li::before {
display: inline-block;
vertical-align: middle;
content: counter(chaptersCounter) " ";
margin-bottom: 0.875rem;
color: #aaa;
text-align: center;
width: 1em;
margin-right: 0.625em;
font-weight: 300;
float: left; }
ol.chapters > li.coming-soon::before {
opacity: 0; }
ol.chapters > li.coming-soon a {
font-size: 0.8em;
margin-top: 0.2em;
opacity: 0.4; }
ol.chapters:first-child {
counter-reset: chaptersCounter; }
ol.chapters a {
display: inline-block;
vertical-align: middle;
margin-bottom: 1rem; }
ol.chapters, ul.potions, .preface-link {
font-weight: 300;
letter-spacing: 0.01em;
margin-right: -0.01em;
font-size: 1.25em;
line-height: 1;
position: relative;
width: 14em;
max-width: 100%;
text-align: left;
margin: 0 auto;
padding: 0 1rem; }
@media (min-width: 44rem) {
ol.chapters, ul.potions, .preface-link {
font-size: 1.75rem; } }
@media (min-width: 72rem) {
ol.chapters, ul.potions, .preface-link {
font-size: 2rem; } }
ol.chapters a, ul.potions a, .preface-link a {
color: inherit;
text-decoration: none;
white-space: nowrap; }
html[data-user-agent*="Chrome"] ol.chapters a:hover span, html[data-user-agent*="Chrome"] ul.potions a:hover span, html[data-user-agent*="Chrome"] .preface-link a:hover span {
background: linear-gradient(#ffffff, #ffffff), linear-gradient(#ffffff, #ffffff), linear-gradient(#464646, #464646);
background-size: 0.05em 2px, 0.05em 2px, 2px 2px;
background-repeat: no-repeat, no-repeat, repeat-x;
text-shadow: 0.03em 0 #fff, -0.03em 0 #fff, 0 0.03em #fff, 0 -0.03em #fff, 0.06em 0 #fff, -0.06em 0 #fff, 0.09em 0 #fff, -0.09em 0 #fff;
background-position-y: 88%, 88%, 88%;
background-position-x: 0%, 100%, 0%; }
html[data-user-agent*="Chrome"] ol.chapters a:hover span::selection, html[data-user-agent*="Chrome"] ul.potions a:hover span::selection, html[data-user-agent*="Chrome"] .preface-link a:hover span::selection {
text-shadow: 0.03em 0 currentColor, -0.03em 0 currentColor, 0 0.03em currentColor, 0 -0.03em currentColor, 0.06em 0 currentColor, -0.06em 0 currentColor, 0.09em 0 currentColor, -0.09em 0 currentColor;
background: currentColor; }
html[data-user-agent*="Chrome"] ol.chapters a:hover span::-moz-selection, html[data-user-agent*="Chrome"] ul.potions a:hover span::-moz-selection, html[data-user-agent*="Chrome"] .preface-link a:hover span::-moz-selection {
text-shadow: 0.03em 0 currentColor, -0.03em 0 currentColor, 0 0.03em currentColor, 0 -0.03em currentColor, 0.06em 0 currentColor, -0.06em 0
gitextract_ajwg6exb/
├── .gitignore
├── 404.html
├── LICENSE.md
├── README.md
├── chapters/
│ ├── 1-the-box/
│ │ ├── images/
│ │ │ └── box-model.sketch/
│ │ │ ├── Data
│ │ │ ├── metadata
│ │ │ └── version
│ │ └── index.html
│ ├── 2-layout/
│ │ └── index.html
│ ├── 3-tables/
│ │ └── index.html
│ ├── 4-color/
│ │ └── index.html
│ ├── 5-typography/
│ │ └── index.html
│ ├── 6-transitions/
│ │ └── index.html
│ ├── _template.html
│ └── preface/
│ └── index.html
├── config.rb
├── css/
│ ├── base.css
│ ├── chapter.css
│ ├── eager.css
│ ├── home.css
│ ├── logo.css
│ ├── potions.css
│ └── social.css
├── fool-github/
│ ├── css.css
│ └── more-css.css
├── index.html
├── js/
│ ├── chapters.coffee
│ ├── chapters.js
│ ├── footer.coffee
│ ├── footer.js
│ ├── home.coffee
│ └── home.js
├── magician-helpers/
│ └── blackboard/
│ └── index.html
├── planning/
│ └── planning.md
├── potions/
│ ├── buttons/
│ │ └── index.html
│ ├── content-reordering/
│ │ └── index.html
│ ├── letter-spacing/
│ │ └── index.html
│ ├── overflow-ellipsis/
│ │ ├── config.rb
│ │ ├── css/
│ │ │ └── overflow-ellipsis.css
│ │ ├── index.html
│ │ └── sass/
│ │ └── overflow-ellipsis.sass
│ ├── potpourri/
│ │ └── index.html
│ ├── table-styling/
│ │ ├── config.rb
│ │ ├── css/
│ │ │ └── table-styling.css
│ │ ├── index.html
│ │ └── sass/
│ │ └── table-styling.sass
│ ├── three-pane-app/
│ │ ├── config.rb
│ │ ├── css/
│ │ │ └── three-pane-app.css
│ │ ├── index.html
│ │ └── sass/
│ │ └── three-pane-app.sass
│ ├── three-pane-app-with-color/
│ │ ├── config.rb
│ │ ├── css/
│ │ │ └── three-pane-app-with-color.css
│ │ ├── index.html
│ │ └── sass/
│ │ └── three-pane-app-with-color.sass
│ └── two-pane-app/
│ ├── config.rb
│ ├── css/
│ │ └── two-pane-app.css
│ ├── index.html
│ └── sass/
│ └── two-pane-app.sass
└── sass/
├── _colors.sass
├── _rainbow.sass
├── _variables.sass
├── base.sass
├── chapter.sass
├── eager.sass
├── home.sass
├── logo.sass
├── potions.sass
└── social.sass
Condensed preview — 68 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (818K chars).
[
{
"path": ".gitignore",
"chars": 11,
"preview": ".sass-cache"
},
{
"path": "404.html",
"chars": 1981,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <title>Page not found — Magic of CSS — Adam Sch"
},
{
"path": "LICENSE.md",
"chars": 1054,
"preview": "Copyright © 2014 Adam Schwartz\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this sof"
},
{
"path": "README.md",
"chars": 839,
"preview": "## The Magic of CSS\n\n> A CSS course for web developers who want to be magicians.\n\n- [The Magic of CSS](http://adamschwar"
},
{
"path": "chapters/1-the-box/images/box-model.sketch/metadata",
"chars": 598,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "chapters/1-the-box/images/box-model.sketch/version",
"chars": 2,
"preview": "18"
},
{
"path": "chapters/1-the-box/index.html",
"chars": 11681,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <title>The Box — Chapter 1 — Magic of CSS — Ada"
},
{
"path": "chapters/2-layout/index.html",
"chars": 28696,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <title>Layout — Chapter 2 — Magic of CSS — Adam"
},
{
"path": "chapters/3-tables/index.html",
"chars": 22415,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <title>Tables — Chapter 3 — Magic of CSS — Adam"
},
{
"path": "chapters/4-color/index.html",
"chars": 24299,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <title>Color — Chapter 4 — Magic of CSS — Adam "
},
{
"path": "chapters/5-typography/index.html",
"chars": 18590,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <title>Typography — Chapter 5 — Magic of CSS — "
},
{
"path": "chapters/6-transitions/index.html",
"chars": 35084,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <title>Transitions — Chapter 6 — Magic of CSS —"
},
{
"path": "chapters/_template.html",
"chars": 3065,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <title>ChapterName — Chapter # — Magic of CSS —"
},
{
"path": "chapters/preface/index.html",
"chars": 3744,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <title>Preface — Magic of CSS — Adam Schwartz</"
},
{
"path": "config.rb",
"chars": 101,
"preview": "css_dir = \"css\"\nsass_dir = \"sass\"\noutput_style = :nested\nrelative_assets = true\nline_comments = false"
},
{
"path": "css/base.css",
"chars": 3485,
"preview": "@font-face {\n font-family: \"social-icons\";\n src: url(data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAAc"
},
{
"path": "css/chapter.css",
"chars": 35049,
"preview": "@charset \"UTF-8\";\n@font-face {\n font-family: \"social-icons\";\n src: url(data:application/x-font-woff;charset=utf-8;base"
},
{
"path": "css/eager.css",
"chars": 2627,
"preview": ".eager {\n display: block;\n text-align: center;\n padding-left: 1em;\n padding-right: 1em; }\n .eager .eager-outer {\n "
},
{
"path": "css/home.css",
"chars": 7725,
"preview": "body {\n margin: 0; }\n @media (min-width: 44rem) {\n body {\n margin: 8em 0; } }\n\n.page {\n text-align: center;\n "
},
{
"path": "css/logo.css",
"chars": 5897,
"preview": ".logo {\n display: block;\n text-decoration: none;\n font-size: 0.75rem;\n height: 10.875em;\n width: 18.4375em;\n margi"
},
{
"path": "css/potions.css",
"chars": 445,
"preview": ".mock-paragraph b {\n display: inline-block;\n vertical-align: middle;\n *vertical-align: auto;\n *zoom: 1;\n *display: "
},
{
"path": "css/social.css",
"chars": 2614,
"preview": "@font-face {\n font-family: \"social-icons\";\n src: url(data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAAc"
},
{
"path": "fool-github/css.css",
"chars": 204800,
"preview": ".lots-and-lots-of-css {}\n.lots-and-lots-of-css {}\n.lots-and-lots-of-css {}\n.lots-and-lots-of-css {}\n.lots-and-lots-of-cs"
},
{
"path": "fool-github/more-css.css",
"chars": 204800,
"preview": ".lots-and-lots-of-css {}\n.lots-and-lots-of-css {}\n.lots-and-lots-of-css {}\n.lots-and-lots-of-css {}\n.lots-and-lots-of-cs"
},
{
"path": "index.html",
"chars": 3753,
"preview": "<!DOCTYPE html>\n<html class=\"home-page\">\n <head>\n <meta charset=\"utf-8\">\n <title>Magic of CSS — Adam Sc"
},
{
"path": "js/chapters.coffee",
"chars": 17103,
"preview": "chapters = {}\n\napplyToParents = (node, apply, count = 0) ->\n if count is 10\n return\n if node.parentNode and"
},
{
"path": "js/chapters.js",
"chars": 17245,
"preview": "(function() {\n var applyToParents, chapters, specialTermTitle;\n\n chapters = {};\n\n applyToParents = function(node, app"
},
{
"path": "js/footer.coffee",
"chars": 3407,
"preview": "setupCarbonAds = ->\n page = document.querySelector('.page')\n return unless page\n\n el = document.createElement '"
},
{
"path": "js/footer.js",
"chars": 13,
"preview": "// footer.js\n"
},
{
"path": "js/home.coffee",
"chars": 841,
"preview": "document.documentElement.setAttribute? 'data-user-agent', navigator.userAgent\n\nfiredScroll = false\nwindow.addEventListen"
},
{
"path": "js/home.js",
"chars": 1155,
"preview": "(function() {\n var base, firedScroll, ref, referrerHostname;\n\n if (typeof (base = document.documentElement).setAttribu"
},
{
"path": "magician-helpers/blackboard/index.html",
"chars": 4566,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <title>Blackboard — Magic of CSS — Adam Schwart"
},
{
"path": "planning/planning.md",
"chars": 1076,
"preview": "Planned chapters:\n\n- Units (px, em, rem, %)\n- Media Queries / Responsive Design\n- Animations\n- HTML and Body\n - http:"
},
{
"path": "potions/buttons/index.html",
"chars": 10480,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <title>Buttons — Magic of CSS — Adam Schwartz</"
},
{
"path": "potions/content-reordering/index.html",
"chars": 17682,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <title>Content Reordering — Magic of CSS — Adam"
},
{
"path": "potions/letter-spacing/index.html",
"chars": 3034,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <title>Letter Spacing — Potion — Magic of CSS —"
},
{
"path": "potions/overflow-ellipsis/config.rb",
"chars": 101,
"preview": "css_dir = \"css\"\nsass_dir = \"sass\"\noutput_style = :nested\nrelative_assets = true\nline_comments = false"
},
{
"path": "potions/overflow-ellipsis/css/overflow-ellipsis.css",
"chars": 433,
"preview": ".overflow-ellipsis-simple {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n width: 20em;\n backg"
},
{
"path": "potions/overflow-ellipsis/index.html",
"chars": 3608,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <title>Overflow Ellipsis — Potion — Magic of CS"
},
{
"path": "potions/overflow-ellipsis/sass/overflow-ellipsis.sass",
"chars": 445,
"preview": "@import compass/css3\n\n.overflow-ellipsis-simple\n overflow: hidden\n text-overflow: ellipsis\n white-space: nowrap"
},
{
"path": "potions/potpourri/index.html",
"chars": 12951,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <title>Potpourri — Magic of CSS — Adam Schwartz"
},
{
"path": "potions/table-styling/config.rb",
"chars": 101,
"preview": "css_dir = \"css\"\nsass_dir = \"sass\"\noutput_style = :nested\nrelative_assets = true\nline_comments = false"
},
{
"path": "potions/table-styling/css/table-styling.css",
"chars": 1145,
"preview": "table {\n border-collapse: collapse;\n border-spacing: 0; }\n table th {\n vertical-align: bottom; }\n table th, table"
},
{
"path": "potions/table-styling/index.html",
"chars": 5582,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <title>Table Styling — Potion — Magic of CSS — "
},
{
"path": "potions/table-styling/sass/table-styling.sass",
"chars": 931,
"preview": "@import compass/css3\n\n// Content\n\ntable\n border-collapse: collapse\n border-spacing: 0\n\n th\n vertical-ali"
},
{
"path": "potions/three-pane-app/config.rb",
"chars": 101,
"preview": "css_dir = \"css\"\nsass_dir = \"sass\"\noutput_style = :nested\nrelative_assets = true\nline_comments = false"
},
{
"path": "potions/three-pane-app/css/three-pane-app.css",
"chars": 1894,
"preview": "html, body {\n height: 100%;\n overflow: hidden; }\n\n.three-pane-app {\n position: absolute;\n top: 0;\n left: 0;\n botto"
},
{
"path": "potions/three-pane-app/index.html",
"chars": 5550,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <title>Three Pane App — Potion — Magic of CSS —"
},
{
"path": "potions/three-pane-app/sass/three-pane-app.sass",
"chars": 1625,
"preview": "@import compass/css3\n\nhtml, body\n height: 100%\n overflow: hidden\n\n.three-pane-app\n position: absolute\n top: "
},
{
"path": "potions/three-pane-app-with-color/config.rb",
"chars": 101,
"preview": "css_dir = \"css\"\nsass_dir = \"sass\"\noutput_style = :nested\nrelative_assets = true\nline_comments = false"
},
{
"path": "potions/three-pane-app-with-color/css/three-pane-app-with-color.css",
"chars": 835,
"preview": ".three-pane-app.three-pane-app-with-color .top {\n border-bottom-color: rgba(52, 133, 204, 0.2);\n background: #3485cc; "
},
{
"path": "potions/three-pane-app-with-color/index.html",
"chars": 5678,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <title>Three Pane App with Color — Potion — Mag"
},
{
"path": "potions/three-pane-app-with-color/sass/three-pane-app-with-color.sass",
"chars": 670,
"preview": ".three-pane-app.three-pane-app-with-color\n\n .top\n border-bottom-color: rgba(52, 133, 204, 0.2)\n backgro"
},
{
"path": "potions/two-pane-app/config.rb",
"chars": 101,
"preview": "css_dir = \"css\"\nsass_dir = \"sass\"\noutput_style = :nested\nrelative_assets = true\nline_comments = false"
},
{
"path": "potions/two-pane-app/css/two-pane-app.css",
"chars": 1589,
"preview": "html, body {\n height: 100%;\n overflow: hidden; }\n\n.two-pane-app {\n position: absolute;\n top: 0;\n left: 0;\n bottom:"
},
{
"path": "potions/two-pane-app/index.html",
"chars": 2553,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <title>Two Pane App — Potion — Magic of CSS — A"
},
{
"path": "potions/two-pane-app/sass/two-pane-app.sass",
"chars": 1343,
"preview": "@import compass/css3\n\nhtml, body\n height: 100%\n overflow: hidden\n\n.two-pane-app\n position: absolute\n top: 0\n"
},
{
"path": "sass/_colors.sass",
"chars": 127,
"preview": "$purple: #6335e6\n$blue: #0085ae\n$green: #8ebd14\n$yellow: #ffc359\n$orange: #ff716a\n$red: #ff3283\n\n$selectionColor: curren"
},
{
"path": "sass/_rainbow.sass",
"chars": 1954,
"preview": "@import compass/css3\n$supported-browsers: reject(browsers(), \"android\", \"android-chrome\", \"android-firefox\", \"blackberry"
},
{
"path": "sass/_variables.sass",
"chars": 163,
"preview": "$chapterWidth: 36rem\n$chapterBreakPoint: $chapterWidth + (2 * 1rem)\n$chapterBreakPointLarge: $chapterWidth + (2 * 4rem)\n"
},
{
"path": "sass/base.sass",
"chars": 930,
"preview": "@import compass/css3\n@import compass/utilities/general/clearfix\n\n@import colors\n@import variables\n\n@import social\n\n*, *:"
},
{
"path": "sass/chapter.sass",
"chars": 19923,
"preview": "@import compass/css3\n@import compass/utilities/general/clearfix\n\n@import colors\n@import variables\n\n@import social\n\nbody\n"
},
{
"path": "sass/eager.sass",
"chars": 2579,
"preview": "@import compass/css3\n@import compass/utilities/general/clearfix\n\n@import colors\n\n.eager\n display: block\n text-alig"
},
{
"path": "sass/home.sass",
"chars": 6535,
"preview": "@import compass/css3\n@import compass/utilities/general/clearfix\n\n@import rainbow\n@import colors\n@import variables\n\nbody\n"
},
{
"path": "sass/logo.sass",
"chars": 2129,
"preview": "@import compass/css3\n\n@import rainbow\n\n.logo\n display: block\n text-decoration: none\n font-size: .75rem\n heig"
},
{
"path": "sass/potions.sass",
"chars": 373,
"preview": "@import compass/css3\n@import compass/utilities/general/clearfix\n\n.mock-paragraph b\n +inline-block\n background: rgb"
},
{
"path": "sass/social.sass",
"chars": 2613,
"preview": "@font-face\n font-family: \"social-icons\"\n src: url(data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAA"
}
]
// ... and 1 more files (download for full content)
About this extraction
This page contains the full source code of the adamschwartz/magic-of-css GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 68 files (766.2 KB), approximately 233.5k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.