├── .gitignore ├── 404.html ├── LICENSE.md ├── README.md ├── chapters ├── 1-the-box │ ├── images │ │ ├── box-model.sketch │ │ │ ├── Data │ │ │ ├── QuickLook │ │ │ │ ├── Preview.png │ │ │ │ └── Thumbnail.png │ │ │ ├── metadata │ │ │ └── version │ │ └── box-model.svg │ └── index.html ├── 2-layout │ └── index.html ├── 3-tables │ └── index.html ├── 4-color │ ├── images │ │ └── all-rgb.png │ └── 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 ├── favicon.ico ├── fool-github ├── css.css └── more-css.css ├── index.html ├── js ├── chapters.coffee ├── chapters.js ├── footer.coffee ├── footer.js ├── home.coffee └── home.js ├── logo.png ├── magician-helpers └── blackboard │ └── index.html ├── media ├── ebook-cover-large.png └── ebook-cover.png ├── planning ├── css-selectors.png └── 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-with-color │ ├── config.rb │ ├── css │ │ └── three-pane-app-with-color.css │ ├── index.html │ └── sass │ │ └── three-pane-app-with-color.sass ├── three-pane-app │ ├── config.rb │ ├── css │ │ └── three-pane-app.css │ ├── index.html │ └── sass │ │ └── three-pane-app.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 /.gitignore: -------------------------------------------------------------------------------- 1 | .sass-cache -------------------------------------------------------------------------------- /404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Page not found — Magic of CSS — Adam Schwartz 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright © 2014 Adam Schwartz 2 | 3 | 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: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## The Magic of CSS 2 | 3 | > A CSS course for web developers who want to be magicians. 4 | 5 | - [The Magic of CSS](http://adamschwartz.co/magic-of-css) 6 | - [Preface](http://adamschwartz.co/magic-of-css/chapters/preface) 7 | - [Chapter 1: The Box](http://adamschwartz.co/magic-of-css/chapters/1-the-box) 8 | - [Chapter 2: Layout](http://adamschwartz.co/magic-of-css/chapters/2-layout) 9 | - [Chapter 3: Tables](http://adamschwartz.co/magic-of-css/chapters/3-tables) 10 | - [Chapter 4: Color](http://adamschwartz.co/magic-of-css/chapters/4-color/) 11 | - [Chapter 5: Typography](http://adamschwartz.co/magic-of-css/chapters/5-typography) 12 | - [Chapter 6: Transitions](http://adamschwartz.co/magic-of-css/chapters/6-transitions/) 13 | - See [planning.md](https://github.com/adamschwartz/magic-of-css/blob/gh-pages/planning/planning.md) for what’s next... -------------------------------------------------------------------------------- /chapters/1-the-box/images/box-model.sketch/Data: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamschwartz/magic-of-css/066aa596b420029f72b553f027773c5de74c1b21/chapters/1-the-box/images/box-model.sketch/Data -------------------------------------------------------------------------------- /chapters/1-the-box/images/box-model.sketch/QuickLook/Preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamschwartz/magic-of-css/066aa596b420029f72b553f027773c5de74c1b21/chapters/1-the-box/images/box-model.sketch/QuickLook/Preview.png -------------------------------------------------------------------------------- /chapters/1-the-box/images/box-model.sketch/QuickLook/Thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamschwartz/magic-of-css/066aa596b420029f72b553f027773c5de74c1b21/chapters/1-the-box/images/box-model.sketch/QuickLook/Thumbnail.png -------------------------------------------------------------------------------- /chapters/1-the-box/images/box-model.sketch/metadata: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | app 6 | com.bohemiancoding.sketch 7 | build 8 | 5355 9 | commit 10 | b7d299b0a34651d1a0e066786b75aa36168d5809 11 | fonts 12 | 13 | Monaco 14 | Monaco 15 | Monaco 16 | Monaco 17 | 18 | length 19 | 23101 20 | version 21 | 18 22 | 23 | 24 | -------------------------------------------------------------------------------- /chapters/1-the-box/images/box-model.sketch/version: -------------------------------------------------------------------------------- 1 | 18 -------------------------------------------------------------------------------- /chapters/1-the-box/images/box-model.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | box-model 4 | Created with Sketch (http://www.bohemiancoding.com/sketch) 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | content 14 | 15 | 16 | margin 17 | 18 | 19 | padding 20 | 21 | 22 | border 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /chapters/1-the-box/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | The Box — Chapter 1 — Magic of CSS — Adam Schwartz 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 |
22 |

23 | Chapter 1 24 | The Box 25 |

26 | 27 |

Box model

28 | 29 |

In CSS, the box model[1] describes the rectangular boxes that are generated for elements laid out in the page.

30 | 31 |

Essentially, everything is a rectangle.

32 | 33 |
34 | 35 |
36 |
37 | A picture of the box model[1] 38 |
39 |
40 |
41 | 42 |

Some interesting facts:

43 | 48 | 49 | 61 | 62 |
63 |

Quick note: most CSS properties in this textbook can be clicked to obtain contextual information. Try clicking box-shadow, for example.

64 |
65 | 66 |

Box sizing

67 | 68 |

The box-sizing property gives you a little control around how boxes are sized within this model. The two possible values for box-sizing are content-box and border-box[2].

69 | 70 |
71 |
content-box
72 |
The default. When computing the size of a box, padding and border are added.
73 |
border-box
74 |
When computing the size of a box, padding and border are folded in.
75 |
76 | 77 |

For example:

78 | 79 |

Example

80 | 81 |

Both of these boxes have the following CSS, but one has box-sizing content-box and the other border-box.

82 | 83 |
84 | 92 | 93 |
.box {
 94 |     height: 5em;
 95 |     width: 5em;
 96 |     padding: 1em;
 97 |     border: .25em solid
 98 | }
99 | 100 |
101 |
102 |

content-box

103 |
104 |
105 |
106 |
107 |
108 |

border-box

109 |
110 |
111 |
112 |
113 |
114 |
115 | 116 |

In the border-box case, the width and height of the .box are 5em, exactly what we set. In the content-box case, the width and height are 7.5em = 5 + (2 * 1) + (2 * .25), since we need to include the padding and border on both sides.

117 | 118 |

Flexible inputs

119 | 120 |

One of the benefits of using border-box is you can set a padding and width of mixed units without creating strange sizing edge cases. One fantastic use for this is creating flexible inputs with a fixed padding size.

121 | 122 |

In the example below, our input has a specific padding in ems and yet we can still specify a width in % (padding: .4em .55em and width: 100%, respectively).

123 | 124 |
125 | 156 | 157 |
input[type="text"] {
158 |     /* Flexibility */
159 |     box-sizing: border-box;
160 |     width: 100%;
161 | 
162 |     /* Styling */
163 |     padding: .4em .55em;
164 |     font-size: inherit;
165 |     font-family: inherit;
166 |     color: inherit;
167 |     border: 0;
168 |     border-radius: .25em;
169 |     outline: none
170 | }
171 | 172 |
173 |
174 |
175 |
176 |

Box

177 | 178 |
179 |
180 |
181 |

182 | 183 |   width: 75% 184 |

185 | 186 |

Adjust the box width and observe the input sizes itself perfectly within the box while maintaining a fixed padding.

187 |
188 |
189 | 190 | 205 | 206 |

tl;dr

207 | 208 |

If you want height and width to behave in the most intuitive way, listen to Paul Irish[3] and put this at the top of your CSS:

209 | 210 |
html {
211 |   box-sizing: border-box
212 | }
213 | *, *::before, *::after {
214 |   box-sizing: inherit
215 | }
216 | 217 |
218 | 219 |

Further reading

220 | 221 | 225 | 226 |

Citations

227 | 228 |
    229 |
  1. w3: Box model
  2. 230 |
  3. MDN: box-sizing — There is also padding-box, but don’t worry about that.
  4. 231 |
  5. Paul Irish: * { Box-sizing: Border-box } FTW
  6. 232 |
233 | 234 |
235 | 236 | 245 |
246 |
247 | 248 | 249 | 250 | 251 | -------------------------------------------------------------------------------- /chapters/4-color/images/all-rgb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamschwartz/magic-of-css/066aa596b420029f72b553f027773c5de74c1b21/chapters/4-color/images/all-rgb.png -------------------------------------------------------------------------------- /chapters/_template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ChapterName — Chapter # — Magic of CSS — Adam Schwartz 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 |
22 |

23 | Chapter # 24 | ChapterName 25 |

26 | 27 |
28 | 29 |

Further reading

30 | 31 | 34 | 35 |

Citations

36 | 37 |
    38 |
  1. 39 |
40 | 41 |
42 | 43 | 53 |
54 |
55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /chapters/preface/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Preface — Magic of CSS — Adam Schwartz 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 |
22 |

23 | Preface 24 |

25 | 26 |

CSS is a mess. 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. Magic is a codification of what I’ve learned in that crazy process.

27 | 28 |

The material in this textbook is intermediate-to-advanced. It assumes an understanding of the CSS syntax, cascading and inheritance, and commonly used selectors. It also assumes you’ve had enough experience with CSS to have learned not to make these common mistakes anymore.

29 | 30 |

As always, feedback is welcome. I hope you enjoy reading Magic.

31 | 32 |
33 | 34 | 40 |
41 |
42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /config.rb: -------------------------------------------------------------------------------- 1 | css_dir = "css" 2 | sass_dir = "sass" 3 | output_style = :nested 4 | relative_assets = true 5 | line_comments = false -------------------------------------------------------------------------------- /css/base.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "social-icons"; 3 | src: url(data:application/x-font-woff;charset=utf-8;base64,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) format("woff"); 4 | font-weight: normal; 5 | font-style: normal; } 6 | *, *::after, *::before { 7 | box-sizing: border-box; } 8 | 9 | ::-moz-selection { 10 | text-shadow: none; 11 | background: currentColor; 12 | color: #fff; } 13 | 14 | ::selection { 15 | text-shadow: none; 16 | background: currentColor; 17 | color: #fff; } 18 | 19 | html { 20 | font-size: 16px; 21 | --purple: #6335e6; 22 | --blue: #0085ae; 23 | --green: #8ebd14; 24 | --yellow: #ffc359; 25 | --orange: #ff716a; 26 | --red: #ff3283; } 27 | @media (min-width: 72rem) { 28 | html { 29 | font-size: 20px; } } 30 | 31 | body { 32 | font-family: Avenir, "Helvetica Neue", sans-serif; 33 | background: #fff; 34 | color: #000; 35 | margin: 0; 36 | text-rendering: optimizeLegibility; 37 | -webkit-font-smoothing: antialiased; 38 | -webkit-text-size-adjust: 100%; } 39 | 40 | h1, h2, h3, h4, h5, h6 { 41 | font-weight: 600; } 42 | 43 | a { 44 | color: #0085ae; } 45 | a:visited { 46 | color: #6335e6; } 47 | 48 | .clearfix { 49 | *zoom: 1; } 50 | .clearfix:after { 51 | content: ""; 52 | display: table; 53 | clear: both; } 54 | -------------------------------------------------------------------------------- /css/eager.css: -------------------------------------------------------------------------------- 1 | .eager { 2 | display: block; 3 | text-align: center; 4 | padding-left: 1em; 5 | padding-right: 1em; } 6 | .eager .eager-outer { 7 | -moz-border-radius: 0.3125em; 8 | -webkit-border-radius: 0.3125em; 9 | border-radius: 0.3125em; 10 | padding: 4px; 11 | background-color: #ff3283; 12 | 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%); 13 | display: inline-block; 14 | max-width: 100%; 15 | width: 26em; } 16 | .eager .eager-inner { 17 | -moz-border-radius: 0.1875em; 18 | -webkit-border-radius: 0.1875em; 19 | border-radius: 0.1875em; 20 | background-color: #fff; 21 | background: linear-gradient(rgba(255, 255, 255, 0.91), #ffffff); 22 | padding: 1.125em; } 23 | .eager .smart-underlined { 24 | color: inherit; 25 | text-decoration: none; 26 | background: linear-gradient(#ffffff, #ffffff), linear-gradient(#ffffff, #ffffff), linear-gradient(#333332, #333332); 27 | background-size: 0.05em 1px, 0.05em 1px, 1px 1px; 28 | background-repeat: no-repeat, no-repeat, repeat-x; 29 | 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; 30 | background-position-y: 87%, 87%, 87%; 31 | background-position-x: 0%, 100%, 0%; } 32 | .eager .smart-underlined::selection { 33 | 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; 34 | background: currentColor; } 35 | .eager .smart-underlined::-moz-selection { 36 | 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; 37 | background: currentColor; } 38 | .eager h1 { 39 | font-size: 1em; 40 | margin: 0 0 1em; } 41 | .eager p { 42 | margin: 1em 0 0; } 43 | .eager p.small { 44 | font-size: 0.8em; 45 | padding: 0 2em; 46 | line-height: 1.33em; 47 | margin-bottom: -0.2em; } 48 | .eager a.eager-button { 49 | text-decoration: none; 50 | display: block; 51 | cursor: pointer; 52 | -moz-border-radius: 10em; 53 | -webkit-border-radius: 10em; 54 | border-radius: 10em; 55 | font-weight: bold; 56 | padding: 0.7em 1.2em; 57 | background: #4039a5; 58 | color: #fff; } 59 | -------------------------------------------------------------------------------- /css/home.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; } 3 | @media (min-width: 44rem) { 4 | body { 5 | margin: 8em 0; } } 6 | 7 | .page { 8 | text-align: center; 9 | padding: 2em 0; } 10 | @media (min-width: 44rem) { 11 | .page { 12 | padding: 0; } } 13 | 14 | .separator { 15 | height: 2.5em; } 16 | @media (min-width: 44rem) { 17 | .separator { 18 | height: 10em; } } 19 | 20 | p.author { 21 | font-size: 1.4rem; 22 | margin-top: 2em; 23 | letter-spacing: 0.05em; 24 | padding-left: 0.43em; 25 | color: #888; 26 | font-weight: 300; } 27 | p.author a { 28 | text-decoration: none; 29 | color: inherit; } 30 | 31 | .share { 32 | margin-top: -0.7rem; 33 | margin-bottom: 0.7rem; 34 | padding-left: 0.6rem; 35 | font-size: 0; } 36 | .share iframe { 37 | display: inline-block; 38 | vertical-align: middle; 39 | background: #eee; 40 | border-radius: 5px; 41 | margin-left: auto; 42 | margin-right: auto; 43 | border: 0; 44 | height: 2.4rem; 45 | width: 13.6rem; 46 | height: 1.6rem; 47 | opacity: 0.8; } 48 | .share iframe:hover { 49 | opacity: 1; } 50 | .share iframe.github { 51 | width: 8rem; } 52 | 53 | h2 { 54 | font-weight: 300; 55 | text-transform: uppercase; 56 | letter-spacing: 0.4em; 57 | font-size: 1.375em; 58 | line-height: 1; 59 | position: relative; 60 | margin: 2.5rem 0; 61 | color: #aaa; 62 | padding: 0 1rem; } 63 | h2 span { 64 | margin-right: -0.4em; } 65 | @media (min-width: 44rem) { 66 | h2 { 67 | margin: 5rem 0; } } 68 | 69 | ol.chapters { 70 | list-style-type: none; 71 | margin-left: 0; } 72 | ol.chapters > li { 73 | clear: left; 74 | counter-increment: chaptersCounter; } 75 | ol.chapters > li:after { 76 | content: ""; 77 | display: table; 78 | clear: both; } 79 | ol.chapters > li::before { 80 | display: inline-block; 81 | vertical-align: middle; 82 | content: counter(chaptersCounter) " "; 83 | margin-bottom: 0.875rem; 84 | color: #aaa; 85 | text-align: center; 86 | width: 1em; 87 | margin-right: 0.625em; 88 | font-weight: 300; 89 | float: left; } 90 | ol.chapters > li.coming-soon::before { 91 | opacity: 0; } 92 | ol.chapters > li.coming-soon a { 93 | font-size: 0.8em; 94 | margin-top: 0.2em; 95 | opacity: 0.4; } 96 | ol.chapters:first-child { 97 | counter-reset: chaptersCounter; } 98 | ol.chapters a { 99 | display: inline-block; 100 | vertical-align: middle; 101 | margin-bottom: 1rem; } 102 | 103 | ol.chapters, ul.potions, .preface-link { 104 | font-weight: 300; 105 | letter-spacing: 0.01em; 106 | margin-right: -0.01em; 107 | font-size: 1.25em; 108 | line-height: 1; 109 | position: relative; 110 | width: 14em; 111 | max-width: 100%; 112 | text-align: left; 113 | margin: 0 auto; 114 | padding: 0 1rem; } 115 | @media (min-width: 44rem) { 116 | ol.chapters, ul.potions, .preface-link { 117 | font-size: 1.75rem; } } 118 | @media (min-width: 72rem) { 119 | ol.chapters, ul.potions, .preface-link { 120 | font-size: 2rem; } } 121 | ol.chapters a, ul.potions a, .preface-link a { 122 | color: inherit; 123 | text-decoration: none; 124 | white-space: nowrap; } 125 | 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 { 126 | background: linear-gradient(#ffffff, #ffffff), linear-gradient(#ffffff, #ffffff), linear-gradient(#464646, #464646); 127 | background-size: 0.05em 2px, 0.05em 2px, 2px 2px; 128 | background-repeat: no-repeat, no-repeat, repeat-x; 129 | 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; 130 | background-position-y: 88%, 88%, 88%; 131 | background-position-x: 0%, 100%, 0%; } 132 | 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 { 133 | 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; 134 | background: currentColor; } 135 | 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 { 136 | 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; 137 | background: currentColor; } 138 | html[data-user-agent*="Chrome"] ol.chapters a:hover span[data-starts-with="T"], html[data-user-agent*="Chrome"] ul.potions a:hover span[data-starts-with="T"], html[data-user-agent*="Chrome"] .preface-link a:hover span[data-starts-with="T"] { 139 | background-size: 0.15em 2px, 0.05em 2px, 2px 2px; } 140 | 141 | ul.potions, .preface-link { 142 | list-style: none; 143 | text-align: center; } 144 | ul.potions li, .preface-link li { 145 | margin-bottom: 0.5em; } 146 | 147 | .logo.animated .the-magic-of { 148 | transition: opacity 800ms 1300ms ease-in-out; 149 | opacity: 0; } 150 | .trigger-pageload-animations .logo.animated .the-magic-of { 151 | opacity: 1; } 152 | .logo.animated .css-rainbow .rainbow { 153 | -webkit-backface-visibility: hidden; } 154 | .logo.animated .css-rainbow .css-rainbow-c .rainbow { 155 | transition: transform 800ms 0ms ease-in-out; 156 | transform: rotateZ(90deg); } 157 | .trigger-pageload-animations .logo.animated .css-rainbow .css-rainbow-c .rainbow { 158 | transform: rotateZ(-90deg); } 159 | .logo.animated .css-rainbow .css-rainbow-s-1 .bottom-half .rainbow { 160 | transition: transform 400ms 600ms ease-in; 161 | transform: rotateZ(270deg); } 162 | .trigger-pageload-animations .logo.animated .css-rainbow .css-rainbow-s-1 .bottom-half .rainbow { 163 | transform: rotateZ(90deg); } 164 | .logo.animated .css-rainbow .css-rainbow-s-1 .top-half .rainbow { 165 | transition: transform 400ms 1000ms ease-out; 166 | transform: rotateZ(90deg); } 167 | .trigger-pageload-animations .logo.animated .css-rainbow .css-rainbow-s-1 .top-half .rainbow { 168 | transform: rotateZ(270deg); } 169 | .logo.animated .css-rainbow .css-rainbow-s-2 .bottom-half .rainbow { 170 | transition: transform 400ms 800ms ease-in; 171 | transform: rotateZ(270deg); } 172 | .trigger-pageload-animations .logo.animated .css-rainbow .css-rainbow-s-2 .bottom-half .rainbow { 173 | transform: rotateZ(90deg); } 174 | .logo.animated .css-rainbow .css-rainbow-s-2 .top-half .rainbow { 175 | transition: transform 400ms 1200ms ease-out; 176 | transform: rotateZ(90deg); } 177 | .trigger-pageload-animations .logo.animated .css-rainbow .css-rainbow-s-2 .top-half .rainbow { 178 | transform: rotateZ(270deg); } 179 | 180 | .page-inner > *:not(.logo) { 181 | transition: opacity 800ms 1300ms ease-in-out; 182 | opacity: 0; } 183 | .trigger-pageload-animations .page-inner > *:not(.logo) { 184 | opacity: 1; } 185 | .window-has-been-scrolled .page-inner > *:not(.logo), .has-been-here-before .page-inner > *:not(.logo) { 186 | transition: none; } 187 | 188 | .trigger-pageload-animations.trigger-pageload-animations-3s .logo.animated:hover .css-rainbow .css-rainbow-c .rainbow { 189 | transition: transform 800ms 1200ms ease-in-out; 190 | transform: rotateZ(90deg); } 191 | .trigger-pageload-animations.trigger-pageload-animations-3s .logo.animated:hover .css-rainbow .css-rainbow-s-1 .bottom-half .rainbow { 192 | transition: transform 400ms 1000ms ease-out; 193 | transform: rotateZ(270deg); } 194 | .trigger-pageload-animations.trigger-pageload-animations-3s .logo.animated:hover .css-rainbow .css-rainbow-s-1 .top-half .rainbow { 195 | transition: transform 400ms 600ms ease-in; 196 | transform: rotateZ(90deg); } 197 | .trigger-pageload-animations.trigger-pageload-animations-3s .logo.animated:hover .css-rainbow .css-rainbow-s-2 .bottom-half .rainbow { 198 | transition: transform 400ms 400ms ease-out; 199 | transform: rotateZ(270deg); } 200 | .trigger-pageload-animations.trigger-pageload-animations-3s .logo.animated:hover .css-rainbow .css-rainbow-s-2 .top-half .rainbow { 201 | transition: transform 400ms 0ms ease-in; 202 | transform: rotateZ(90deg); } 203 | -------------------------------------------------------------------------------- /css/logo.css: -------------------------------------------------------------------------------- 1 | .logo { 2 | display: block; 3 | text-decoration: none; 4 | font-size: 0.75rem; 5 | height: 10.875em; 6 | width: 18.4375em; 7 | margin: 0 auto; 8 | max-width: 100%; 9 | text-align: center; } 10 | .logo .the-magic-of { 11 | font-weight: 300; 12 | text-transform: uppercase; 13 | letter-spacing: 0.4em; 14 | font-size: 1.375em; 15 | height: 1em; 16 | line-height: 1; 17 | margin: 0 0 1em; 18 | overflow: hidden; 19 | position: relative; 20 | left: 0.2em; 21 | margin-bottom: 1.27273em; 22 | color: #aaa; } 23 | .logo .css-rainbow { 24 | max-width: 100%; 25 | white-space: nowrap; } 26 | .logo .css-rainbow .css-letter { 27 | display: inline-block; 28 | vertical-align: middle; } 29 | .logo .css-rainbow .css-rainbow-c { 30 | position: relative; 31 | overflow: hidden; 32 | width: 3.825em; 33 | height: 7.75em; 34 | margin-right: 3.175em; } 35 | .logo .css-rainbow .css-rainbow-c .rainbow { 36 | transform: rotateZ(90deg); 37 | transform-origin: 50% 100%; 38 | height: 3.875em; 39 | width: 7.75em; 40 | overflow: hidden; 41 | position: relative; 42 | transform: rotateZ(-90deg); 43 | position: absolute; } 44 | .logo .css-rainbow .css-rainbow-c .rainbow .bands { 45 | position: absolute; 46 | top: 0; 47 | left: 0; 48 | height: 3.875em; 49 | width: 7.75em; 50 | overflow: hidden; } 51 | .logo .css-rainbow .css-rainbow-c .rainbow .bands::before { 52 | box-shadow: inset 0 0 0 3.375em #6335e6, inset 0 0 0 2.8125em #0085ae, inset 0 0 0 2.25em #8ebd14, inset 0 0 0 1.6875em #ffc359, inset 0 0 0 1.125em #ff716a, inset 0 0 0 0.5625em #ff3283; 53 | box-shadow: inset 0 0 0 0.5625em #ff3283, inset 0 0 0 1.125em #ff716a, inset 0 0 0 1.6875em #ffc359, inset 0 0 0 2.25em #8ebd14, inset 0 0 0 2.8125em #0085ae, inset 0 0 0 3.375em #6335e6; 54 | border-radius: 50%; 55 | content: ""; 56 | display: block; 57 | position: absolute; 58 | margin: auto; 59 | left: 0; 60 | right: 0; 61 | bottom: -3.875em; 62 | height: 7.75em; 63 | width: 7.75em; } 64 | .logo .css-rainbow .css-rainbow-s { 65 | transform: translate3d(0, 0, 0) rotateZ(22.5deg); 66 | width: 5em; 67 | height: 7.75em; 68 | position: relative; 69 | top: 0.15em; } 70 | .logo .css-rainbow .css-rainbow-s .rainbow { 71 | position: absolute; } 72 | .logo .css-rainbow .css-rainbow-s .top-half { 73 | position: absolute; 74 | overflow: hidden; 75 | width: 2.5em; 76 | height: 5em; } 77 | .logo .css-rainbow .css-rainbow-s .top-half .rainbow { 78 | transform: rotateZ(90deg); 79 | transform-origin: 50% 100%; 80 | height: 2.5em; 81 | width: 5em; 82 | overflow: hidden; 83 | position: relative; 84 | transform: rotateZ(-90deg); } 85 | .logo .css-rainbow .css-rainbow-s .top-half .rainbow .bands { 86 | position: absolute; 87 | top: 0; 88 | left: 0; 89 | height: 2.5em; 90 | width: 5em; 91 | overflow: hidden; } 92 | .logo .css-rainbow .css-rainbow-s .top-half .rainbow .bands::before { 93 | box-shadow: inset 0 0 0 2.25em #6335e6, inset 0 0 0 1.875em #0085ae, inset 0 0 0 1.5em #8ebd14, inset 0 0 0 1.125em #ffc359, inset 0 0 0 0.75em #ff716a, inset 0 0 0 0.375em #ff3283; 94 | box-shadow: inset 0 0 0 0.375em #ff3283, inset 0 0 0 0.75em #ff716a, inset 0 0 0 1.125em #ffc359, inset 0 0 0 1.5em #8ebd14, inset 0 0 0 1.875em #0085ae, inset 0 0 0 2.25em #6335e6; 95 | border-radius: 50%; 96 | content: ""; 97 | display: block; 98 | position: absolute; 99 | margin: auto; 100 | left: 0; 101 | right: 0; 102 | bottom: -2.5em; 103 | height: 5em; 104 | width: 5em; } 105 | .logo .css-rainbow .css-rainbow-s .bottom-half { 106 | position: absolute; 107 | overflow: hidden; 108 | width: 2.5em; 109 | height: 5em; 110 | top: 2.75em; 111 | left: 2.5em; 112 | left: 2.45em; } 113 | .logo .css-rainbow .css-rainbow-s .bottom-half .rainbow { 114 | transform: rotateZ(90deg); 115 | transform-origin: 50% 100%; 116 | height: 2.5em; 117 | width: 5em; 118 | overflow: hidden; 119 | position: relative; 120 | transform: rotateZ(90deg); 121 | left: -2.5em; } 122 | .logo .css-rainbow .css-rainbow-s .bottom-half .rainbow .bands { 123 | position: absolute; 124 | top: 0; 125 | left: 0; 126 | height: 2.5em; 127 | width: 5em; 128 | overflow: hidden; } 129 | .logo .css-rainbow .css-rainbow-s .bottom-half .rainbow .bands::before { 130 | box-shadow: inset 0 0 0 2.25em #6335e6, inset 0 0 0 1.875em #0085ae, inset 0 0 0 1.5em #8ebd14, inset 0 0 0 1.125em #ffc359, inset 0 0 0 0.75em #ff716a, inset 0 0 0 0.375em #ff3283; 131 | box-shadow: inset 0 0 0 2.25em #ff3283, inset 0 0 0 1.875em #ff716a, inset 0 0 0 1.5em #ffc359, inset 0 0 0 1.125em #8ebd14, inset 0 0 0 0.75em #0085ae, inset 0 0 0 0.375em #6335e6; 132 | box-shadow: inset 0 0 0 0.375em #ff3283, inset 0 0 0 0.75em #ff716a, inset 0 0 0 1.125em #ffc359, inset 0 0 0 1.5em #8ebd14, inset 0 0 0 1.875em #0085ae, inset 0 0 0 2.25em #6335e6; 133 | box-shadow: inset 0 0 0 0.375em #6335e6, inset 0 0 0 0.75em #0085ae, inset 0 0 0 1.125em #8ebd14, inset 0 0 0 1.5em #ffc359, inset 0 0 0 1.875em #ff716a, inset 0 0 0 2.25em #ff3283; 134 | border-radius: 50%; 135 | content: ""; 136 | display: block; 137 | position: absolute; 138 | margin: auto; 139 | left: 0; 140 | right: 0; 141 | bottom: -2.5em; 142 | height: 5em; 143 | width: 5em; } 144 | .logo .css-rainbow .css-rainbow-s.css-rainbow-s-1 { 145 | margin-right: 1.875em; } 146 | .logo .css-rainbow .css-rainbow-s.css-rainbow-s-2 { 147 | margin-right: -0.4375em; } 148 | @media (min-width: 48em) { 149 | .logo { 150 | font-size: 1rem; } } 151 | -------------------------------------------------------------------------------- /css/potions.css: -------------------------------------------------------------------------------- 1 | .mock-paragraph b { 2 | display: inline-block; 3 | vertical-align: middle; 4 | *vertical-align: auto; 5 | *zoom: 1; 6 | *display: inline; 7 | background: rgba(0, 0, 0, 0.1); 8 | width: 3.125em; 9 | height: 0.5em; 10 | margin-right: 0.3125em; 11 | margin-bottom: 0.3125em; } 12 | .mock-paragraph b:nth-last-child(4n+1) { 13 | width: 4.5625em; } 14 | .mock-paragraph b:nth-last-child(10n+1) { 15 | width: 0.875em; } 16 | .mock-paragraph b:nth-last-child(9n+1) { 17 | width: 5em; } 18 | -------------------------------------------------------------------------------- /css/social.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "social-icons"; 3 | src: url(data:application/x-font-woff;charset=utf-8;base64,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) format("woff"); 4 | font-weight: normal; 5 | font-style: normal; } 6 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamschwartz/magic-of-css/066aa596b420029f72b553f027773c5de74c1b21/favicon.ico -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Magic of CSS — Adam Schwartz 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 | 21 |

by @adamfschwartz

22 | 25 |
26 | 29 |

Chapters

30 |
    31 |
  1. The Box
  2. 32 |
  3. Layout
  4. 33 |
  5. Tables
  6. 34 |
  7. Color
  8. 35 |
  9. Typography
  10. 36 |
  11. Transitions
  12. 37 |
  13. Coming soon...
  14. 38 |
39 |

Potions

40 | 50 |
51 |
52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /js/chapters.coffee: -------------------------------------------------------------------------------- 1 | chapters = {} 2 | 3 | applyToParents = (node, apply, count = 0) -> 4 | if count is 10 5 | return 6 | if node.parentNode and node.parentNode.tagName isnt 'BODY' 7 | applyToParents node.parentNode, apply, count + 1 8 | apply node 9 | 10 | specialTermTitle = (specialTerm) -> 11 | title = specialTerm.replace(/\-/g, ' ') 12 | title[0].toUpperCase() + title[1..] 13 | 14 | chapters.specialTerms = 15 | 'em': 16 | description: '

A unit of measurement which represents a multiple of the current font-size in pixels

' 17 | exampleCSS: 'font-size: 2em' 18 | exampleHTML: '
Some text
' 19 | 20 | '%': 21 | description: '

A relative unit of measurement

' 22 | exampleCSS: 'width: 80%' 23 | exampleHTML: '
' 24 | 25 | 'box-sizing': 26 | description: '

Controls how element boxes are sized

' 27 | exampleCSS: 'width: 75%;\npadding-left: 25%' 28 | exampleHTML: ''' 29 | 38 |
content-box
39 |

The content is sized to 75% so the padding is added.

40 |
border-box
41 |

The border is sized to 75% so the padding is absorbed.

42 | ''' 43 | 44 | 'border-box': 'box-sizing' 45 | 'content-box': 'box-sizing' 46 | 'padding-box': 'box-sizing' 47 | 48 | 'outline': 49 | description: '

A line outside the box

' 50 | exampleCSS: 'outline: 1em double green' 51 | exampleHTML: '
' 52 | 53 | 'border-radius': 54 | description: '

Rounded corners

' 55 | exampleCSS: 'border-radius: 0 1em' 56 | exampleHTML: '
' 57 | 58 | 'box-shadow': 59 | description: '

A shadow-like styling of an element box

' 60 | exampleCSS: 'box-shadow:\n 0 1em 4em pink,\n 0 .1em red,\n inset 0 .5em #000' 61 | exampleHTML: '
' 62 | 63 | 'inline-block': 64 | description: ''' 65 |

A value for the display property.

66 |

The inside of me is formatted as block, but the element myself is laid into the page as an inline element.

67 | ''' 68 | exampleCSS: 'display: inline-block' 69 | exampleHTML: 'Text
Inline block
more text...' 70 | 71 | 'block': 72 | description: ''' 73 |

A value for the display property.

74 |

My width is sized by my parent and I can have widths and heights set on me. My height is determined by my content.

75 | ''' 76 | exampleCSS: 'display: block' 77 | exampleHTML: 'Text
Block
more text...' 78 | 79 | 'inline': 80 | description: ''' 81 |

A value for the display property.

82 |

My width and height are determined by my contents and widths and heights don’t do anything to me. Think of me like a word flowing in a paragraph.

83 | ''' 84 | exampleCSS: 'display: inline' 85 | exampleHTML: 'Text
Inline
more text...' 86 | 87 | 'top, left, right, bottom': 88 | description: '

Positioning properties

' 89 | exampleCSS: 'position: absolute;\ntop: 1em;\nleft: 3em' 90 | exampleHTML: ''' 91 |
92 |
93 |
94 | ''' 95 | 96 | 'position': 'top, left, right, bottom' 97 | 'position: absolute': 'top, left, right, bottom' 98 | 99 | 'top': 'top, left, right, bottom' 100 | 'left': 'top, left, right, bottom' 101 | 'right': 'top, left, right, bottom' 102 | 'bottom': 'top, left, right, bottom' 103 | 104 | 'font-smoothing': 105 | description: '

Determines the type of antialiasing used in rendering text

' 106 | exampleHTML: ''' 107 |
subpixel-antialiased
108 |
antialiased
109 |
none
110 | ''' 111 | 112 | '-webkit-font-smoothing': 'font-smoothing' 113 | '-webkit-font-smoothing: antialiased': 'font-smoothing' 114 | 'antialiased': 'font-smoothing' 115 | '-webkit-font-smoothing: subpixel-antialiased': 'font-smoothing' 116 | 'subpixel-antialiased': 'font-smoothing' 117 | 118 | 'font-family': 119 | description: '

Family of fonts to be used for the element text

' 120 | exampleHTML: 'inherit, serif, monospace' 121 | 122 | 'font-size': 123 | description: '

Size of element text. (Also sets the base for em values for child elements.)

' 124 | exampleHTML: 'inherit, 18px, 10px' 125 | 126 | 'font-weight': 127 | description: '

The weight (or thickness) of element text

' 128 | exampleHTML: 'inherit, bold, 100' 129 | 130 | 'font-style': 131 | description: '

Used for italic

' 132 | exampleHTML: 'inherit, italic' 133 | 134 | 'font-variant': 135 | description: '

Used for small capitals

' 136 | exampleHTML: 'inherit, small-caps' 137 | 138 | 'text-align': 139 | description: '

Horizontal alignement of element text

' 140 | exampleHTML: ''' 141 |
left
142 |
center
143 |
right
144 | ''' 145 | 146 | 'text-decoration': 147 | description: '

Decorate element text with a horizontal line above, below, or through the text

' 148 | exampleHTML: 'inherit, underline, overline, line-through' 149 | 150 | 'text-indent': 151 | description: '

Indentation of the first line of element text

' 152 | exampleHTML: ''' 153 |
This sentence has no text indentation.
154 |
This sentence has 5em text indentation.
155 |
This sentence has -50px text indentation.
156 | ''' 157 | 158 | 'text-shadow': 159 | description: '

A shadow-like styling of element box

' 160 | exampleCSS: 'text-shadow:\n 0 0 .4em red,\n 1em 1em green' 161 | exampleHTML: '
Text shadow
' 162 | 163 | 'text-transform': 164 | description: '

Typographical styling of text-transform

' 165 | exampleHTML: ''' 166 |
none
167 |
lowercase
168 |
uppercase
169 |
capitalize
170 | ''' 171 | 172 | 'letter-spacing': 173 | description: '

Additional space to the right of each letter of element text

' 174 | exampleHTML: ''' 175 |
none
176 |
.05em
177 |
1em
178 |
-2px
179 | ''' 180 | 181 | 'white-space': 182 | description: '

See MDN: white-space.

' 183 | 184 | 'white-space: nowrap': 'white-space' 185 | 186 | 'line-height': 187 | description: 'The height of each line of text' 188 | exampleHTML: ''' 189 |
line-height: 1em
190 |
line-height: 5em
191 | ''' 192 | 193 | 'word-spacing': 194 | description: 'Additional space to the right of each word of element text' 195 | exampleHTML: ''' 196 |
none none
197 |
1em 1em
198 |
5em 5em
199 |
-8px -8px
200 | ''' 201 | 202 | 'opacity': 203 | description: '

Render an element partially or completely transparent

' 204 | exampleCSS: 'opacity: 50%' 205 | exampleHTML: ''' 206 |
207 |
208 | ''' 209 | 210 | 'mix-blend-mode': 211 | description: '

Adjust the way an element blends with what’s behind it, similar to features often found in image software with layers

' 212 | exampleCSS: 'mix-blend-mode: multiply' 213 | exampleHTML: ''' 214 |
215 |
216 |

Options include:

217 |
normal\nmultiply\nscreen\noverlay\ndarken\nlighten\ncolor-dodge\ncolor-burn\nhard-light\nsoft-light\ndifference\nexclusion\nhue\nsaturation\ncolor\nluminosity
218 | ''' 219 | 220 | chapters.init = -> 221 | chapters.setupUserAgentDataAttribute() 222 | chapters.setupContextualCodeExamples() 223 | chapters.setupSocialFooter() 224 | chapters.setupGlobalNavigation() 225 | 226 | chapters.setupUserAgentDataAttribute = -> 227 | document.documentElement.setAttribute? 'data-user-agent', navigator.userAgent 228 | 229 | chapters.setupContextualCodeExamples = -> 230 | return unless /(Chrome|iPad|iPhone|iPod)/g.test navigator.userAgent 231 | 232 | contextualDisplayWrapper = document.createElement('div') 233 | contextualDisplayWrapper.classList.add 'contextual-display-wrapper' 234 | 235 | contextualDisplay = document.createElement('div') 236 | contextualDisplay.classList.add 'contextual-display' 237 | 238 | contextualDisplayWrapper.appendChild contextualDisplay 239 | 240 | document.querySelector('.chapter').appendChild contextualDisplayWrapper 241 | 242 | document.body.addEventListener 'click', (event) -> 243 | closeContextualDisplay() 244 | 245 | Array::slice.call(document.querySelectorAll(':not(pre) > code')).forEach (code) -> 246 | for specialTerm of chapters.specialTerms when code.textContent is specialTerm 247 | code.classList.add 'contextual-code-example' 248 | return 249 | 250 | if location.hostname.match(/localhost/)?.length and window.console?.log? 251 | console.log 'Could not find special term', code.textContent 252 | 253 | closeContextualDisplay = -> 254 | Array::slice.call(document.querySelectorAll('.contextual-open, .contextual-transition, .contextual-open-tree')).forEach (element) -> 255 | element.classList.remove 'contextual-open' 256 | element.classList.remove 'contextual-open-tree' 257 | element.classList.remove 'contextual-open-tree-parent' 258 | 259 | Array::slice.call(document.querySelectorAll('.contextual-code-example')).forEach (code) -> 260 | code.addEventListener 'click', (event) -> 261 | event.stopPropagation() 262 | 263 | if event.target.classList.contains 'contextual-open-tree' 264 | closeContextualDisplay() 265 | return 266 | 267 | specialTermObj = chapters.specialTerms[event.target.textContent] 268 | specialTerm = event.target.textContent 269 | 270 | if typeof specialTermObj is 'string' 271 | specialTerm = specialTermObj 272 | specialTermObj = chapters.specialTerms[specialTermObj] 273 | 274 | if specialTermObj? 275 | closeContextualDisplay() 276 | 277 | exampleCSSSelector = specialTermObj.exampleCSSSelector 278 | if not exampleCSSSelector and specialTermObj.exampleCSS and specialTermObj.exampleHTML 279 | fragment = document.createDocumentFragment() 280 | div = document.createElement 'div' 281 | div.innerHTML = specialTermObj.exampleHTML 282 | fragment.appendChild div 283 | el = fragment.querySelector '[class]' 284 | if el 285 | firstClass = el.getAttribute('class').trim().split(' ')[0] 286 | exampleCSSSelector = '.' + firstClass 287 | 288 | exampleCSS = if specialTermObj.exampleCSS then """ 289 |
#{ specialTermObj.exampleCSS }
290 | 295 | """ else '' 296 | 297 | exampleHTML = if specialTermObj.exampleHTML then """ 298 |
299 | #{ specialTermObj.exampleHTML } 300 |
301 | """ else '' 302 | 303 | contextualDisplay.innerHTML = """ 304 |

#{ specialTermTitle specialTerm }

305 |
306 | #{ specialTermObj.description } 307 |
308 | #{ exampleCSS } 309 | #{ exampleHTML } 310 | 311 | """ 312 | 313 | contextualDisplay.querySelector('[data-contextual-close]')?.addEventListener 'click', (event) -> 314 | event.stopPropagation() 315 | closeContextualDisplay() 316 | 317 | contextualDisplay.clientHeight 318 | 319 | positionContextualDisplay code 320 | code.parentNode.classList.add 'contextual-open-tree-parent' 321 | 322 | contextualDisplay.classList.add 'contextual-open' 323 | applyToParents code, (node) -> node.classList.add 'contextual-open-tree' 324 | document.body.classList.add 'contextual-open' 325 | 326 | else 327 | closeContextualDisplay() 328 | 329 | positionContextualDisplay = (code) -> 330 | boundingClientRect = code.getBoundingClientRect() 331 | contextualDisplay.style.top = (boundingClientRect.top + (document.body.scrollTop || document.documentElement.scrollTop)) + 'px' 332 | contextualDisplay.clientHeight 333 | 334 | contextualDisplayWrapper.style.height = document.body.clientHeight + 'px' 335 | 336 | window.addEventListener 'resize', -> 337 | if document.body.classList.contains 'contextual-open' 338 | positionContextualDisplay document.querySelector('code.contextual-code-example.contextual-open-tree') 339 | 340 | chapters.setupSocialFooter = -> 341 | page = document.querySelector('.page') 342 | return unless page 343 | 344 | page.insertAdjacentHTML 'beforebegin', """ 345 |
346 | Code on GitHub 347 | 348 |
349 | """ 350 | 351 | chapters.setupGlobalNavigation = -> 352 | nav = document.querySelector('nav.chapter-navigation') 353 | page = document.querySelector('.page') 354 | return unless nav and page 355 | 356 | previousLink = nav.querySelector('.previous-chapter') 357 | nextLink = nav.querySelector('.next-chapter') 358 | 359 | html = '' 376 | 377 | page.insertAdjacentHTML 'afterend', html 378 | 379 | window.chapters = chapters 380 | addEventListener 'DOMContentLoaded', -> chapters.init() 381 | -------------------------------------------------------------------------------- /js/chapters.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | var applyToParents, chapters, specialTermTitle; 3 | 4 | chapters = {}; 5 | 6 | applyToParents = function(node, apply, count) { 7 | if (count == null) { 8 | count = 0; 9 | } 10 | if (count === 10) { 11 | return; 12 | } 13 | if (node.parentNode && node.parentNode.tagName !== 'BODY') { 14 | applyToParents(node.parentNode, apply, count + 1); 15 | } 16 | return apply(node); 17 | }; 18 | 19 | specialTermTitle = function(specialTerm) { 20 | var title; 21 | title = specialTerm.replace(/\-/g, ' '); 22 | return title[0].toUpperCase() + title.slice(1); 23 | }; 24 | 25 | chapters.specialTerms = { 26 | 'em': { 27 | description: '

A unit of measurement which represents a multiple of the current font-size in pixels

', 28 | exampleCSS: 'font-size: 2em', 29 | exampleHTML: '
Some text
' 30 | }, 31 | '%': { 32 | description: '

A relative unit of measurement

', 33 | exampleCSS: 'width: 80%', 34 | exampleHTML: '
' 35 | }, 36 | 'box-sizing': { 37 | description: '

Controls how element boxes are sized

', 38 | exampleCSS: 'width: 75%;\npadding-left: 25%', 39 | exampleHTML: '\n
content-box
\n

The content is sized to 75% so the padding is added.

\n
border-box
\n

The border is sized to 75% so the padding is absorbed.

' 40 | }, 41 | 'border-box': 'box-sizing', 42 | 'content-box': 'box-sizing', 43 | 'padding-box': 'box-sizing', 44 | 'outline': { 45 | description: '

A line outside the box

', 46 | exampleCSS: 'outline: 1em double green', 47 | exampleHTML: '
' 48 | }, 49 | 'border-radius': { 50 | description: '

Rounded corners

', 51 | exampleCSS: 'border-radius: 0 1em', 52 | exampleHTML: '
' 53 | }, 54 | 'box-shadow': { 55 | description: '

A shadow-like styling of an element box

', 56 | exampleCSS: 'box-shadow:\n 0 1em 4em pink,\n 0 .1em red,\n inset 0 .5em #000', 57 | exampleHTML: '
' 58 | }, 59 | 'inline-block': { 60 | description: '

A value for the display property.

\n

The inside of me is formatted as block, but the element myself is laid into the page as an inline element.

', 61 | exampleCSS: 'display: inline-block', 62 | exampleHTML: 'Text
Inline block
more text...' 63 | }, 64 | 'block': { 65 | description: '

A value for the display property.

\n

My width is sized by my parent and I can have widths and heights set on me. My height is determined by my content.

', 66 | exampleCSS: 'display: block', 67 | exampleHTML: 'Text
Block
more text...' 68 | }, 69 | 'inline': { 70 | description: '

A value for the display property.

\n

My width and height are determined by my contents and widths and heights don’t do anything to me. Think of me like a word flowing in a paragraph.

', 71 | exampleCSS: 'display: inline', 72 | exampleHTML: 'Text
Inline
more text...' 73 | }, 74 | 'top, left, right, bottom': { 75 | description: '

Positioning properties

', 76 | exampleCSS: 'position: absolute;\ntop: 1em;\nleft: 3em', 77 | exampleHTML: '
\n
\n
' 78 | }, 79 | 'position': 'top, left, right, bottom', 80 | 'position: absolute': 'top, left, right, bottom', 81 | 'top': 'top, left, right, bottom', 82 | 'left': 'top, left, right, bottom', 83 | 'right': 'top, left, right, bottom', 84 | 'bottom': 'top, left, right, bottom', 85 | 'font-smoothing': { 86 | description: '

Determines the type of antialiasing used in rendering text

', 87 | exampleHTML: '
subpixel-antialiased
\n
antialiased
\n
none
' 88 | }, 89 | '-webkit-font-smoothing': 'font-smoothing', 90 | '-webkit-font-smoothing: antialiased': 'font-smoothing', 91 | 'antialiased': 'font-smoothing', 92 | '-webkit-font-smoothing: subpixel-antialiased': 'font-smoothing', 93 | 'subpixel-antialiased': 'font-smoothing', 94 | 'font-family': { 95 | description: '

Family of fonts to be used for the element text

', 96 | exampleHTML: 'inherit, serif, monospace' 97 | }, 98 | 'font-size': { 99 | description: '

Size of element text. (Also sets the base for em values for child elements.)

', 100 | exampleHTML: 'inherit, 18px, 10px' 101 | }, 102 | 'font-weight': { 103 | description: '

The weight (or thickness) of element text

', 104 | exampleHTML: 'inherit, bold, 100' 105 | }, 106 | 'font-style': { 107 | description: '

Used for italic

', 108 | exampleHTML: 'inherit, italic' 109 | }, 110 | 'font-variant': { 111 | description: '

Used for small capitals

', 112 | exampleHTML: 'inherit, small-caps' 113 | }, 114 | 'text-align': { 115 | description: '

Horizontal alignement of element text

', 116 | exampleHTML: '
left
\n
center
\n
right
' 117 | }, 118 | 'text-decoration': { 119 | description: '

Decorate element text with a horizontal line above, below, or through the text

', 120 | exampleHTML: 'inherit, underline, overline, line-through' 121 | }, 122 | 'text-indent': { 123 | description: '

Indentation of the first line of element text

', 124 | exampleHTML: '
This sentence has no text indentation.
\n
This sentence has 5em text indentation.
\n
This sentence has -50px text indentation.
' 125 | }, 126 | 'text-shadow': { 127 | description: '

A shadow-like styling of element box

', 128 | exampleCSS: 'text-shadow:\n 0 0 .4em red,\n 1em 1em green', 129 | exampleHTML: '
Text shadow
' 130 | }, 131 | 'text-transform': { 132 | description: '

Typographical styling of text-transform

', 133 | exampleHTML: '
none
\n
lowercase
\n
uppercase
\n
capitalize
' 134 | }, 135 | 'letter-spacing': { 136 | description: '

Additional space to the right of each letter of element text

', 137 | exampleHTML: '
none
\n
.05em
\n
1em
\n
-2px
' 138 | }, 139 | 'white-space': { 140 | description: '

See MDN: white-space.

' 141 | }, 142 | 'white-space: nowrap': 'white-space', 143 | 'line-height': { 144 | description: 'The height of each line of text', 145 | exampleHTML: '
line-height: 1em
\n
line-height: 5em
' 146 | }, 147 | 'word-spacing': { 148 | description: 'Additional space to the right of each word of element text', 149 | exampleHTML: '
none none
\n
1em 1em
\n
5em 5em
\n
-8px -8px
' 150 | }, 151 | 'opacity': { 152 | description: '

Render an element partially or completely transparent

', 153 | exampleCSS: 'opacity: 50%', 154 | exampleHTML: '
\n
' 155 | }, 156 | 'mix-blend-mode': { 157 | description: '

Adjust the way an element blends with what’s behind it, similar to features often found in image software with layers

', 158 | exampleCSS: 'mix-blend-mode: multiply', 159 | exampleHTML: '
\n
\n

Options include:

\n
normal\nmultiply\nscreen\noverlay\ndarken\nlighten\ncolor-dodge\ncolor-burn\nhard-light\nsoft-light\ndifference\nexclusion\nhue\nsaturation\ncolor\nluminosity
' 160 | } 161 | }; 162 | 163 | chapters.init = function() { 164 | chapters.setupUserAgentDataAttribute(); 165 | chapters.setupContextualCodeExamples(); 166 | chapters.setupSocialFooter(); 167 | return chapters.setupGlobalNavigation(); 168 | }; 169 | 170 | chapters.setupUserAgentDataAttribute = function() { 171 | var base; 172 | return typeof (base = document.documentElement).setAttribute === "function" ? base.setAttribute('data-user-agent', navigator.userAgent) : void 0; 173 | }; 174 | 175 | chapters.setupContextualCodeExamples = function() { 176 | var closeContextualDisplay, contextualDisplay, contextualDisplayWrapper, positionContextualDisplay; 177 | if (!/(Chrome|iPad|iPhone|iPod)/g.test(navigator.userAgent)) { 178 | return; 179 | } 180 | contextualDisplayWrapper = document.createElement('div'); 181 | contextualDisplayWrapper.classList.add('contextual-display-wrapper'); 182 | contextualDisplay = document.createElement('div'); 183 | contextualDisplay.classList.add('contextual-display'); 184 | contextualDisplayWrapper.appendChild(contextualDisplay); 185 | document.querySelector('.chapter').appendChild(contextualDisplayWrapper); 186 | document.body.addEventListener('click', function(event) { 187 | return closeContextualDisplay(); 188 | }); 189 | Array.prototype.slice.call(document.querySelectorAll(':not(pre) > code')).forEach(function(code) { 190 | var ref, ref1, specialTerm; 191 | for (specialTerm in chapters.specialTerms) { 192 | if (!(code.textContent === specialTerm)) { 193 | continue; 194 | } 195 | code.classList.add('contextual-code-example'); 196 | return; 197 | } 198 | if (((ref = location.hostname.match(/localhost/)) != null ? ref.length : void 0) && (((ref1 = window.console) != null ? ref1.log : void 0) != null)) { 199 | return console.log('Could not find special term', code.textContent); 200 | } 201 | }); 202 | closeContextualDisplay = function() { 203 | return Array.prototype.slice.call(document.querySelectorAll('.contextual-open, .contextual-transition, .contextual-open-tree')).forEach(function(element) { 204 | element.classList.remove('contextual-open'); 205 | element.classList.remove('contextual-open-tree'); 206 | return element.classList.remove('contextual-open-tree-parent'); 207 | }); 208 | }; 209 | Array.prototype.slice.call(document.querySelectorAll('.contextual-code-example')).forEach(function(code) { 210 | return code.addEventListener('click', function(event) { 211 | var div, el, exampleCSS, exampleCSSSelector, exampleHTML, firstClass, fragment, ref, specialTerm, specialTermObj; 212 | event.stopPropagation(); 213 | if (event.target.classList.contains('contextual-open-tree')) { 214 | closeContextualDisplay(); 215 | return; 216 | } 217 | specialTermObj = chapters.specialTerms[event.target.textContent]; 218 | specialTerm = event.target.textContent; 219 | if (typeof specialTermObj === 'string') { 220 | specialTerm = specialTermObj; 221 | specialTermObj = chapters.specialTerms[specialTermObj]; 222 | } 223 | if (specialTermObj != null) { 224 | closeContextualDisplay(); 225 | exampleCSSSelector = specialTermObj.exampleCSSSelector; 226 | if (!exampleCSSSelector && specialTermObj.exampleCSS && specialTermObj.exampleHTML) { 227 | fragment = document.createDocumentFragment(); 228 | div = document.createElement('div'); 229 | div.innerHTML = specialTermObj.exampleHTML; 230 | fragment.appendChild(div); 231 | el = fragment.querySelector('[class]'); 232 | if (el) { 233 | firstClass = el.getAttribute('class').trim().split(' ')[0]; 234 | exampleCSSSelector = '.' + firstClass; 235 | } 236 | } 237 | exampleCSS = specialTermObj.exampleCSS ? "
" + specialTermObj.exampleCSS + "
\n" : ''; 238 | exampleHTML = specialTermObj.exampleHTML ? "
\n " + specialTermObj.exampleHTML + "\n
" : ''; 239 | contextualDisplay.innerHTML = "

" + (specialTermTitle(specialTerm)) + "

\n
\n " + specialTermObj.description + "\n
\n" + exampleCSS + "\n" + exampleHTML + "\n"; 240 | if ((ref = contextualDisplay.querySelector('[data-contextual-close]')) != null) { 241 | ref.addEventListener('click', function(event) { 242 | event.stopPropagation(); 243 | return closeContextualDisplay(); 244 | }); 245 | } 246 | contextualDisplay.clientHeight; 247 | positionContextualDisplay(code); 248 | code.parentNode.classList.add('contextual-open-tree-parent'); 249 | contextualDisplay.classList.add('contextual-open'); 250 | applyToParents(code, function(node) { 251 | return node.classList.add('contextual-open-tree'); 252 | }); 253 | return document.body.classList.add('contextual-open'); 254 | } else { 255 | return closeContextualDisplay(); 256 | } 257 | }); 258 | }); 259 | positionContextualDisplay = function(code) { 260 | var boundingClientRect; 261 | boundingClientRect = code.getBoundingClientRect(); 262 | contextualDisplay.style.top = (boundingClientRect.top + (document.body.scrollTop || document.documentElement.scrollTop)) + 'px'; 263 | contextualDisplay.clientHeight; 264 | return contextualDisplayWrapper.style.height = document.body.clientHeight + 'px'; 265 | }; 266 | return window.addEventListener('resize', function() { 267 | if (document.body.classList.contains('contextual-open')) { 268 | return positionContextualDisplay(document.querySelector('code.contextual-code-example.contextual-open-tree')); 269 | } 270 | }); 271 | }; 272 | 273 | chapters.setupSocialFooter = function() { 274 | var page; 275 | page = document.querySelector('.page'); 276 | if (!page) { 277 | return; 278 | } 279 | return page.insertAdjacentHTML('beforebegin', "
\n Code on GitHub\n \n
"); 280 | }; 281 | 282 | chapters.setupGlobalNavigation = function() { 283 | var html, nav, nextLink, page, previousLink; 284 | nav = document.querySelector('nav.chapter-navigation'); 285 | page = document.querySelector('.page'); 286 | if (!(nav && page)) { 287 | return; 288 | } 289 | previousLink = nav.querySelector('.previous-chapter'); 290 | nextLink = nav.querySelector('.next-chapter'); 291 | html = ''; 299 | return page.insertAdjacentHTML('afterend', html); 300 | }; 301 | 302 | window.chapters = chapters; 303 | 304 | addEventListener('DOMContentLoaded', function() { 305 | return chapters.init(); 306 | }); 307 | 308 | }).call(this); 309 | -------------------------------------------------------------------------------- /js/footer.coffee: -------------------------------------------------------------------------------- 1 | setupCarbonAds = -> 2 | page = document.querySelector('.page') 3 | return unless page 4 | 5 | el = document.createElement 'carbonads' 6 | el.innerHTML = ''' 7 | 115 |
116 | ''' 117 | document.body.appendChild el 118 | 119 | script = document.createElement 'script' 120 | script.async = true 121 | script.id = '_carbonads_js' 122 | script.src = '//cdn.carbonads.com/carbon.js?serve=CKYILKQE&placement=adamschwartzco' 123 | document.querySelector('.carbonads-wrapper').appendChild script 124 | 125 | setupCarbonAds() unless location.hostname is 'localhost' 126 | -------------------------------------------------------------------------------- /js/footer.js: -------------------------------------------------------------------------------- 1 | // footer.js 2 | -------------------------------------------------------------------------------- /js/home.coffee: -------------------------------------------------------------------------------- 1 | document.documentElement.setAttribute? 'data-user-agent', navigator.userAgent 2 | 3 | firedScroll = false 4 | window.addEventListener 'scroll', -> 5 | return if firedScroll 6 | firedScroll = true 7 | document.body.className += ' window-has-been-scrolled' 8 | 9 | if localStorage.hasBeenHereBefore is true 10 | document.body.className += ' has-been-here-before' 11 | else 12 | localStorage.hasBeenHereBefore = true 13 | 14 | referrerHostname = document.referrer.match(/:\/\/(.[^/]+)/)?[1].split(':')[0] 15 | 16 | unless location.search.match(/animate/)? 17 | if document.location.hostname is referrerHostname or localStorage.hasBeenHereBefore is true or location.search.match(/fast/)? 18 | document.body.className += ' has-been-here-before' 19 | 20 | document.body.className += ' trigger-pageload-animations' 21 | setTimeout (-> document.body.className += ' trigger-pageload-animations-3s'), 3000 22 | -------------------------------------------------------------------------------- /js/home.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | var base, firedScroll, ref, referrerHostname; 3 | 4 | if (typeof (base = document.documentElement).setAttribute === "function") { 5 | base.setAttribute('data-user-agent', navigator.userAgent); 6 | } 7 | 8 | firedScroll = false; 9 | 10 | window.addEventListener('scroll', function() { 11 | if (firedScroll) { 12 | return; 13 | } 14 | firedScroll = true; 15 | return document.body.className += ' window-has-been-scrolled'; 16 | }); 17 | 18 | if (localStorage.hasBeenHereBefore === true) { 19 | document.body.className += ' has-been-here-before'; 20 | } else { 21 | localStorage.hasBeenHereBefore = true; 22 | } 23 | 24 | referrerHostname = (ref = document.referrer.match(/:\/\/(.[^\/]+)/)) != null ? ref[1].split(':')[0] : void 0; 25 | 26 | if (location.search.match(/animate/) == null) { 27 | if (document.location.hostname === referrerHostname || localStorage.hasBeenHereBefore === true || (location.search.match(/fast/) != null)) { 28 | document.body.className += ' has-been-here-before'; 29 | } 30 | } 31 | 32 | document.body.className += ' trigger-pageload-animations'; 33 | 34 | setTimeout((function() { 35 | return document.body.className += ' trigger-pageload-animations-3s'; 36 | }), 3000); 37 | 38 | }).call(this); 39 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamschwartz/magic-of-css/066aa596b420029f72b553f027773c5de74c1b21/logo.png -------------------------------------------------------------------------------- /magician-helpers/blackboard/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Blackboard — Magic of CSS — Adam Schwartz 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 62 | 63 | 64 | 65 | 66 |
67 | 68 | 116 | 117 | -------------------------------------------------------------------------------- /media/ebook-cover-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamschwartz/magic-of-css/066aa596b420029f72b553f027773c5de74c1b21/media/ebook-cover-large.png -------------------------------------------------------------------------------- /media/ebook-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamschwartz/magic-of-css/066aa596b420029f72b553f027773c5de74c1b21/media/ebook-cover.png -------------------------------------------------------------------------------- /planning/css-selectors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamschwartz/magic-of-css/066aa596b420029f72b553f027773c5de74c1b21/planning/css-selectors.png -------------------------------------------------------------------------------- /planning/planning.md: -------------------------------------------------------------------------------- 1 | Planned chapters: 2 | 3 | - Units (px, em, rem, %) 4 | - Media Queries / Responsive Design 5 | - Animations 6 | - HTML and Body 7 | - http://phrogz.net/css/htmlvsbody.html 8 | - Floats 9 | - http://www.w3.org/TR/CSS2/visuren.html#dis-pos-flo 10 | - Flex 11 | - http://css-tricks.com/boxes-fill-height-dont-squish 12 | - http://www.planningforaliens.com/blog/2014/03/11/real-world-flexbox/ 13 | - http://jakearchibald.com/2014/dont-use-flexbox-for-page-layout/ 14 | - General CSS Troubleshooting 15 | - http://tympanus.net/codrops/2013/07/17/troubleshooting-css 16 | 17 | Planned potions: 18 | - Compare `> * selector` with `> :not(fake)` 19 | - `visibility: visible` inside a `visibility: hidden` 20 | 21 | Additions: 22 | 23 | - Typography 24 | - https://bugsnag.com/blog/responsive-typography-with-modular-scale 25 | - http://typogui.de/ 26 | - Presentation framework 27 | - http://markdalgleish.github.io/presentation-build-wars-gulp-vs-grunt 28 | - Color 29 | - https://twitter.com/elisabethirg/status/445896785962479616 30 | - Use this somehow: http://i.imgur.com/obbWKlH.gif 31 | - Mention -webkit-appearance (http://trentwalton.com/2010/07/14/css-webkit-appearance/) 32 | -------------------------------------------------------------------------------- /potions/buttons/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Buttons — Magic of CSS — Adam Schwartz 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 |
22 |

23 | Potion 24 | Buttons 25 |

26 | 27 | 66 | 67 |

The OS/browser default

68 | 69 |
70 | 83 | 84 |
85 | 86 | 87 | 88 | 89 |
90 | 91 | 92 | 93 |
94 | 95 |
96 | 97 |
98 |
99 |
100 | 101 |

The “I’m so flat you can barely tell I’m a button”

102 | 103 |
104 | 127 | 128 |
129 | 130 | 131 | 132 | 133 |
134 | 135 | 136 | 137 |
138 | 139 |
140 | 141 |
142 |
143 |
144 | 145 |

The skeuomorph

146 | 147 |
148 | 178 | 179 |
180 | 181 | 182 | 183 | 184 |
185 | 186 | 187 | 188 |
189 | 190 |
191 | 192 |
193 |
194 |
195 | 196 |

Skeuomorph-liteTM

197 | 198 |
199 | 225 | 226 |
227 | 228 | 229 | 230 | 231 |
232 | 233 | 234 | 235 |
236 | 237 |
238 | 239 |
240 |
241 |
242 | 243 |

The “I pretend I’m flat when really I’m just a different skeuomorph”

244 | 245 |
246 | 278 |
279 | 280 | 281 | 282 | 283 |
284 | 285 | 286 | 287 |
288 | 289 |
290 | 291 |
292 |
293 |
294 |
295 |
296 | 297 | 298 | 299 | 300 | -------------------------------------------------------------------------------- /potions/content-reordering/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Content Reordering — Magic of CSS — Adam Schwartz 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 65 | 66 |
67 |

68 | Potion 69 | Content Reordering 70 |

71 | 72 | 91 | 92 |
93 |
94 |
95 |
96 |
97 | 98 |

When designing a single app to serve as both a mobile and desktop experience, responsive design techniques are used. CSS media queries are used to style content differently based on the screen dimensions, density, and other queryable properties. A common problem—considered a limitation of responsive design—is reordering the content.

99 | 100 |

There are a number of ways to reorder content using CSS, but most of them come with gotchas and caveats. Here is a quick reminder of two common techniques.

101 | 102 |

Technique 1: Positioning
(“The Throw It in the Corner”)

103 | 104 |

Using position is one way to go, but it only works when you know how large your content will be or you can afford to be specific about where you place it. An example of when this might be appropriate is when moving the position of your navigation.

105 | 106 |
107 | 176 | 177 |
178 |
179 |

About

180 | 181 |

This example uses position: absolute to move the nav on mobile devices.

182 |
183 | 191 |
192 |
193 | 194 |

Technique 2: Floats
(“The Grid Framework”)

195 | 196 |

Grid layouts which come with frameworks like Bootstrap and Fluid are a commonly used tool for handling reponsive design, but they only sort-of reorder content. They use float to align blocks side-by-side on large screens and stack them vertically on small ones. When the float is used in the opposite of the language-direction (so right-to-left for English), a reordering of sorts can be achieved.

197 | 198 |
199 | 236 | 237 |
238 |
239 |
240 |

This paragraph will appear on the right on small screens, but on top on large screens.

241 |
242 |
243 |

This paragraph will appear on the left on small screens, but on bottom on large screens.

244 |
245 |
246 |
247 |
248 | 249 |
250 | 251 |

As you can see, neither of these techniques allow you to reorder arbitrary content. For that, we’ll need to dive deep into the chasms that are the w3c specs.

252 | 253 |

A General Solution

254 | 255 |

The solution involves a not-so-well-known element called <ruby>. Introduced way back in 2001 this little element works in IE5+, Chrome, Safari, and Opera, but unfortunately not in Firefox.

256 | 257 |

So what is a <ruby> element?

258 | 259 |

From the current spec:

260 | 261 |
262 | Ruby is the commonly-used name for a run of text that appears alongside another run of text (referred to as the “base”) and serves as an annotation or a pronunciation guide associated with that run of text. 263 |
264 | 265 |
266 | 267 |
268 |
269 | Example of ruby used in Japanese (simple case) 270 |
271 |
272 |
273 | 274 |

(Hopefully you're starting to see where this is going.)

275 | 276 |

So the technique works as follows:

277 | 278 |

First, place one section in an <rb> element and the other in a <rt>. For example:

279 | 280 |
<ruby>
281 |     <rb>
282 |         <span class="section-a">
283 |             Section A content...
284 |         </span>
285 |     </rb>
286 |     <rt>
287 |         <span class="section-b">
288 |             Section B content...
289 |         </span>
290 |     </rt>
291 | <ruby>
292 | 293 |

Without any CSS applied, Section B will appear above Section A. By default, the font-size of Section B will be smaller (since it’s inside an <rt> block), so you may want to sort of reset it with something like this:

294 | 295 |
rt {
296 |     font-size: inherit
297 | }
298 | 299 |

Finally, to “flip” the content order such that Section B appears last, simply set the following CSS on <rt>. 300 | 301 |

rt {
302 |     display: inline
303 | }
304 | 305 |

Use it in a media query at the desired break point.

306 | 307 |
308 | 347 | 348 |
349 | 350 | 351 | 352 | 353 | This is the content of Section A, the one which appears in the DOM first. But the DOM’s got nothin’ on these mad CSS skills. 354 | 355 | 356 | 357 | 358 | 359 | 360 | This is the content of Section B, the one which appears in the DOM last. But the DOM’s got nothin’ on these mad CSS skills. 361 | 362 | 363 | 364 | 365 |
366 |
367 | 368 |

It really is a gem of an idea.

369 | 370 | 413 |
414 |
415 | 416 | 417 | -------------------------------------------------------------------------------- /potions/letter-spacing/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Letter Spacing — Potion — Magic of CSS — Adam Schwartz 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 |
23 |

24 | Potion 25 | Letter Spacing 26 |

27 | 28 |

When adding letter-spacing to some text, take note of the fact that the spacing is added to the right of each letter, not between each letter.

29 | 30 |

This means that if you text-align: center text which has been letter-spaced, the letters won’t be centered unless you make a correction. There are a number of ways to do this, including applying a negative left margin, a left padding, or using text indent.

31 | 32 |

Text indent is perhaps the best method when you can guarantee your text doesn’t wrap. Otherwise, a padding or margin is probably your best bet.

33 | 34 | 47 | 48 |

1em letter-spacing with no left padding:

49 | 50 |
51 |
Page Title
52 |
53 | 54 |

1em letter-spacing with padding-left: 1em:

55 | 56 |
57 |
Page Title
58 |
59 |
60 |
61 | 62 | 63 | -------------------------------------------------------------------------------- /potions/overflow-ellipsis/config.rb: -------------------------------------------------------------------------------- 1 | css_dir = "css" 2 | sass_dir = "sass" 3 | output_style = :nested 4 | relative_assets = true 5 | line_comments = false -------------------------------------------------------------------------------- /potions/overflow-ellipsis/css/overflow-ellipsis.css: -------------------------------------------------------------------------------- 1 | .overflow-ellipsis-simple { 2 | overflow: hidden; 3 | text-overflow: ellipsis; 4 | white-space: nowrap; 5 | width: 20em; 6 | background: #eeeeee; } 7 | 8 | table { 9 | background: transparent; 10 | border-spacing: 0; 11 | border-collapse: collapse; 12 | width: 100%; 13 | margin-bottom: 1em; } 14 | table td { 15 | border: 0.125em solid #cccccc; } 16 | 17 | .overflow-ellipsis-table-cell { 18 | overflow: hidden; 19 | text-overflow: ellipsis; 20 | white-space: nowrap; 21 | width: 25em; } 22 | -------------------------------------------------------------------------------- /potions/overflow-ellipsis/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Overflow Ellipsis — Potion — Magic of CSS — Adam Schwartz 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 |
25 |

26 | Potion 27 | Overflow Ellipsis 28 |

29 | 30 |

Simple

31 | 32 |
This is some text which will overflow. This is some text which will overflow.
33 | 34 |

Line-height: 1

35 | 36 |
J and yjg can sometimes be cut off by overflows.
37 | 38 |

Table

39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 57 | 58 | 59 | 60 | 67 | 68 | 69 |
NameDescription
Example Name 51 |
52 | This is the description of Example Name. This is the description of Example Name. 53 | This is the description of Example Name. This is the description of Example Name. 54 | This is the description of Example Name. This is the description of Example Name. 55 |
56 |
Example Name 61 |
62 | This is the description of Example Name. This is the description of Example Name. 63 | This is the description of Example Name. This is the description of Example Name. 64 | This is the description of Example Name. This is the description of Example Name. 65 |
66 |
70 |
71 |
72 | 73 | -------------------------------------------------------------------------------- /potions/overflow-ellipsis/sass/overflow-ellipsis.sass: -------------------------------------------------------------------------------- 1 | @import compass/css3 2 | 3 | .overflow-ellipsis-simple 4 | overflow: hidden 5 | text-overflow: ellipsis 6 | white-space: nowrap 7 | width: 20em 8 | background: #eee 9 | 10 | table 11 | background: transparent 12 | border-spacing: 0 13 | border-collapse: collapse 14 | width: 100% 15 | margin-bottom: 1em 16 | 17 | td 18 | border: .125em solid #ccc 19 | 20 | .overflow-ellipsis-table-cell 21 | overflow: hidden 22 | text-overflow: ellipsis 23 | white-space: nowrap 24 | width: 25em -------------------------------------------------------------------------------- /potions/potpourri/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Potpourri — Magic of CSS — Adam Schwartz 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 |
22 |

23 | Potion 24 | Potpourri 25 |

26 | 27 | 51 | 52 |

Modern clearfix

53 | 54 |
55 | 73 | 74 |
75 |

76 | 77 | I am a paragraph of text with a floated box inside me. 78 |

79 |
80 |
81 | 82 |

Background grid for checking alignment

83 | 84 |
85 | 96 | 97 |
98 |

When working on something with varying font sizes, it can be helpful to have a grid behind you.

99 |
100 |
101 | 102 |

Equal negative margin and padding

103 | 104 |
105 | 121 | 122 |
123 |

Click me!

124 |
125 |
126 | 127 |

Equal negative margin and padding gotcha

128 | 129 |
130 | 136 | 137 |
138 |

Sometimes you want to increase the size of a hit target without changing its position. Depending on the situation, there may be a number of ways to accomplish this. But a simple and often effective one is to apply a negative margin and padding of the same value. They sort of cancel eachother out while allowing you to increase the hit target region by the size you choose.

139 |
140 |
141 | 142 |

Aligning floated elements of different font sizes

143 | 144 | 145 | 146 | 147 |
148 | 175 | 176 |
177 | 178 | Title 179 | Author 180 | 181 | 182 |
183 | 184 | 185 | Title 186 | 187 | 188 |
189 |
190 | 191 | 192 |

Gradient shadows

193 | 194 |
195 | 217 | 218 | 254 | 255 |
256 |
257 |
258 |
259 |
260 |
261 | 262 |

Inline SVG (checkmark)

263 | 264 |
265 | 273 | 274 |
275 |
276 |
277 |
278 | 279 |

Greyscale

280 | 281 |
282 | 292 | 293 |
294 | 295 |
296 |
297 | 298 |
<svg xmlns=\'http://www.w3.org/2000/svg\'>
299 |     <filter id=\'grayscale\'>
300 |         <feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/>
301 |     </filter>
302 | </svg>
303 | 
304 | 305 |

That's all folks!

306 | 307 | 335 |
336 |
337 | 338 | 339 | -------------------------------------------------------------------------------- /potions/table-styling/config.rb: -------------------------------------------------------------------------------- 1 | css_dir = "css" 2 | sass_dir = "sass" 3 | output_style = :nested 4 | relative_assets = true 5 | line_comments = false -------------------------------------------------------------------------------- /potions/table-styling/css/table-styling.css: -------------------------------------------------------------------------------- 1 | table { 2 | border-collapse: collapse; 3 | border-spacing: 0; } 4 | table th { 5 | vertical-align: bottom; } 6 | table th, table td { 7 | text-align: left; } 8 | table th[data-numeric], table th[data-month-day-year], table td[data-numeric], table td[data-month-day-year] { 9 | text-align: right; } 10 | 11 | table.light-grid { 12 | width: 100%; 13 | background: #f2f2f2; } 14 | table.light-grid th, table.light-grid td { 15 | padding: 0.625em; } 16 | table.light-grid th { 17 | font-weight: bold; } 18 | table.light-grid tbody td { 19 | border-top: 0.0625em solid #e0e0e0; } 20 | 21 | table.content-only { 22 | width: 100%; } 23 | table.content-only th { 24 | font-weight: normal; 25 | border-bottom: 0.0625em solid #e0e0e0; } 26 | table.content-only th, table.content-only td { 27 | padding: 0.625em; } 28 | table.content-only tr > td:first-child, table.content-only tr > th:first-child { 29 | padding-left: 0; } 30 | table.content-only tr > td:last-child, table.content-only tr > th:last-child { 31 | padding-right: 0; } 32 | table.content-only tr:not(:first-child) > td, table.content-only tr:not(:first-child) > th { 33 | padding-top: 0; } 34 | table.content-only tr:last-child > td { 35 | padding-bottom: 0; } 36 | -------------------------------------------------------------------------------- /potions/table-styling/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Table Styling — Potion — Magic of CSS — Adam Schwartz 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 |
25 |

26 | Potion 27 | Table Styling 28 |

29 | 30 |

Light grid

31 | 32 |
33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 |
BrowserUsageInitial releaseStable version
Chrome42.68%September 2, 200831
Internet Explorer25.44%August 16, 199511
Firefox20.01%September 23, 200225
Safari8.39%January 7, 20037
Opera1.03%April 1, 199418
76 | 77 |

Content-only

78 | 79 |
80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 |
BrowserUsageInitial releaseStable version
Chrome42.68%September 2, 200831
Internet Explorer25.44%August 16, 199511
Firefox20.01%September 23, 200225
Safari8.39%January 7, 20037
Opera1.03%April 1, 199418
123 |
124 |
125 | 126 | -------------------------------------------------------------------------------- /potions/table-styling/sass/table-styling.sass: -------------------------------------------------------------------------------- 1 | @import compass/css3 2 | 3 | // Content 4 | 5 | table 6 | border-collapse: collapse 7 | border-spacing: 0 8 | 9 | th 10 | vertical-align: bottom 11 | 12 | th, td 13 | text-align: left 14 | 15 | &[data-numeric], &[data-month-day-year] 16 | text-align: right 17 | 18 | // Light grid style 19 | 20 | table.light-grid 21 | width: 100% 22 | background: #f2f2f2 23 | 24 | th, td 25 | padding: .625em 26 | 27 | th 28 | font-weight: bold 29 | 30 | tbody td 31 | border-top: .0625em solid #e0e0e0 32 | 33 | // Content-only style 34 | 35 | table.content-only 36 | width: 100% 37 | 38 | th 39 | font-weight: normal 40 | border-bottom: .0625em solid #e0e0e0 41 | 42 | th, td 43 | padding: .625em 44 | 45 | tr 46 | 47 | > td, > th 48 | 49 | &:first-child 50 | padding-left: 0 51 | 52 | &:last-child 53 | padding-right: 0 54 | 55 | &:not(:first-child) 56 | 57 | > td, > th 58 | padding-top: 0 59 | 60 | &:last-child 61 | 62 | > td 63 | padding-bottom: 0 -------------------------------------------------------------------------------- /potions/three-pane-app-with-color/config.rb: -------------------------------------------------------------------------------- 1 | css_dir = "css" 2 | sass_dir = "sass" 3 | output_style = :nested 4 | relative_assets = true 5 | line_comments = false -------------------------------------------------------------------------------- /potions/three-pane-app-with-color/css/three-pane-app-with-color.css: -------------------------------------------------------------------------------- 1 | .three-pane-app.three-pane-app-with-color .top { 2 | border-bottom-color: rgba(52, 133, 204, 0.2); 3 | background: #3485cc; } 4 | .three-pane-app.three-pane-app-with-color .top .title { 5 | background: #c5e4ff; } 6 | .three-pane-app.three-pane-app-with-color .bottom .left { 7 | border-right-color: rgba(52, 133, 204, 0.2); 8 | background: rgba(52, 133, 204, 0.1); } 9 | .three-pane-app.three-pane-app-with-color .bottom .right { 10 | border-left-color: rgba(52, 133, 204, 0.2); 11 | background: rgba(52, 133, 204, 0.1); } 12 | .three-pane-app.three-pane-app-with-color .bottom .item { 13 | border-bottom-color: rgba(52, 133, 204, 0.2); } 14 | .three-pane-app.three-pane-app-with-color .bottom .item:hover { 15 | background: rgba(52, 133, 204, 0.2); 16 | border-bottom-color: rgba(0, 0, 0, 0); } 17 | .three-pane-app.three-pane-app-with-color .title { 18 | background: #3485cc; } 19 | -------------------------------------------------------------------------------- /potions/three-pane-app-with-color/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Three Pane App with Color — Potion — Magic of CSS — Adam Schwartz 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |

57 |

58 |

59 |

60 |

61 |

62 |

63 |

64 |

65 |

66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 | 105 | -------------------------------------------------------------------------------- /potions/three-pane-app-with-color/sass/three-pane-app-with-color.sass: -------------------------------------------------------------------------------- 1 | .three-pane-app.three-pane-app-with-color 2 | 3 | .top 4 | border-bottom-color: rgba(52, 133, 204, 0.2) 5 | background: #3485cc 6 | 7 | .title 8 | background: #c5e4ff 9 | 10 | .bottom 11 | 12 | .left 13 | border-right-color: rgba(52, 133, 204, 0.2) 14 | background: rgba(52, 133, 204, 0.1) 15 | 16 | .right 17 | border-left-color: rgba(52, 133, 204, 0.2) 18 | background: rgba(52, 133, 204, 0.1) 19 | 20 | .item 21 | border-bottom-color: rgba(52, 133, 204, 0.2) 22 | 23 | &:hover 24 | background: rgba(52, 133, 204, 0.2) 25 | border-bottom-color: rgba(0, 0, 0, 0) 26 | 27 | .title 28 | background: #3485cc -------------------------------------------------------------------------------- /potions/three-pane-app/config.rb: -------------------------------------------------------------------------------- 1 | css_dir = "css" 2 | sass_dir = "sass" 3 | output_style = :nested 4 | relative_assets = true 5 | line_comments = false -------------------------------------------------------------------------------- /potions/three-pane-app/css/three-pane-app.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | height: 100%; 3 | overflow: hidden; } 4 | 5 | .three-pane-app { 6 | position: absolute; 7 | top: 0; 8 | left: 0; 9 | bottom: 0; 10 | right: 0; } 11 | .three-pane-app *, .three-pane-app *::after, .three-pane-app *::before { 12 | -webkit-box-sizing: border-box; 13 | -moz-box-sizing: border-box; 14 | box-sizing: border-box; } 15 | .three-pane-app .top { 16 | position: absolute; 17 | height: 3.75em; 18 | padding: 1.25em; 19 | line-height: 2.5em; 20 | width: 100%; 21 | border-bottom: 0.0625em solid rgba(0, 0, 0, 0.1); } 22 | .three-pane-app .bottom { 23 | position: absolute; 24 | top: 3.75em; 25 | bottom: 0; 26 | width: 100%; } 27 | .three-pane-app .bottom .left { 28 | border-right: 0.0625em solid rgba(0, 0, 0, 0.1); 29 | position: absolute; 30 | width: 20%; 31 | height: 100%; 32 | overflow: auto; } 33 | .three-pane-app .bottom .middle { 34 | position: absolute; 35 | width: 60%; 36 | left: 20%; 37 | height: 100%; 38 | overflow: auto; } 39 | .three-pane-app .bottom .middle .page { 40 | width: 40em; 41 | padding: 1.25em; 42 | max-width: 100%; 43 | margin: 0 auto; } 44 | .three-pane-app .bottom .right { 45 | border-left: 0.0625em solid rgba(0, 0, 0, 0.1); 46 | position: absolute; 47 | width: 20%; 48 | right: 0; 49 | height: 100%; 50 | overflow: auto; } 51 | .three-pane-app .bottom .item { 52 | height: 4em; 53 | border-bottom: 0.0625em solid rgba(0, 0, 0, 0.1); 54 | cursor: pointer; } 55 | .three-pane-app .bottom .item:hover { 56 | background: rgba(0, 0, 0, 0.1); 57 | border-bottom: 0.0625em solid rgba(0, 0, 0, 0); } 58 | .three-pane-app .bottom .item:last-child { 59 | border-bottom: 0; } 60 | .three-pane-app .title { 61 | display: -moz-inline-stack; 62 | display: inline-block; 63 | vertical-align: middle; 64 | *vertical-align: auto; 65 | zoom: 1; 66 | *display: inline; 67 | background: rgba(0, 0, 0, 0.1); 68 | width: 10em; 69 | height: 1em; 70 | margin-bottom: 1.25em; } 71 | -------------------------------------------------------------------------------- /potions/three-pane-app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Three Pane App — Potion — Magic of CSS — Adam Schwartz 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |

56 |

57 |

58 |

59 |

60 |

61 |

62 |

63 |

64 |

65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 | 104 | -------------------------------------------------------------------------------- /potions/three-pane-app/sass/three-pane-app.sass: -------------------------------------------------------------------------------- 1 | @import compass/css3 2 | 3 | html, body 4 | height: 100% 5 | overflow: hidden 6 | 7 | .three-pane-app 8 | position: absolute 9 | top: 0 10 | left: 0 11 | bottom: 0 12 | right: 0 13 | 14 | *, *::after, *::before 15 | box-sizing: border-box 16 | 17 | .top 18 | position: absolute 19 | height: 3.75em 20 | padding: 1.25em 21 | line-height: 2.5em 22 | width: 100% 23 | border-bottom: .0625em solid rgba(0, 0, 0, .1) 24 | 25 | .bottom 26 | position: absolute 27 | top: 3.75em 28 | bottom: 0 29 | width: 100% 30 | 31 | .left 32 | border-right: .0625em solid rgba(0, 0, 0, .1) 33 | position: absolute 34 | width: 20% 35 | height: 100% 36 | overflow: auto 37 | 38 | .middle 39 | position: absolute 40 | width: 60% 41 | left: 20% 42 | height: 100% 43 | overflow: auto 44 | 45 | .page 46 | width: 40em 47 | padding: 1.25em 48 | max-width: 100% 49 | margin: 0 auto 50 | 51 | .right 52 | border-left: .0625em solid rgba(0, 0, 0, .1) 53 | position: absolute 54 | width: 20% 55 | right: 0 56 | height: 100% 57 | overflow: auto 58 | 59 | .item 60 | height: 4em 61 | border-bottom: .0625em solid rgba(0, 0, 0, .1) 62 | cursor: pointer 63 | 64 | &:hover 65 | background: rgba(0, 0, 0, .1) 66 | border-bottom: .0625em solid rgba(0, 0, 0, 0) 67 | 68 | &:last-child 69 | border-bottom: 0 70 | 71 | .title 72 | +inline-block 73 | background: rgba(0, 0, 0, .1) 74 | width: 10em 75 | height: 1em 76 | margin-bottom: 1.25em -------------------------------------------------------------------------------- /potions/two-pane-app/config.rb: -------------------------------------------------------------------------------- 1 | css_dir = "css" 2 | sass_dir = "sass" 3 | output_style = :nested 4 | relative_assets = true 5 | line_comments = false -------------------------------------------------------------------------------- /potions/two-pane-app/css/two-pane-app.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | height: 100%; 3 | overflow: hidden; } 4 | 5 | .two-pane-app { 6 | position: absolute; 7 | top: 0; 8 | left: 0; 9 | bottom: 0; 10 | right: 0; } 11 | .two-pane-app *, .two-pane-app *::after, .two-pane-app *::before { 12 | -webkit-box-sizing: border-box; 13 | -moz-box-sizing: border-box; 14 | box-sizing: border-box; } 15 | .two-pane-app .top { 16 | position: absolute; 17 | height: 3.75em; 18 | padding: 1.25em; 19 | line-height: 2.5em; 20 | width: 100%; 21 | border-bottom: 0.0625em solid rgba(0, 0, 0, 0.1); } 22 | .two-pane-app .bottom { 23 | position: absolute; 24 | top: 3.75em; 25 | bottom: 0; 26 | width: 100%; } 27 | .two-pane-app .bottom .left { 28 | border-right: 0.0625em solid rgba(0, 0, 0, 0.1); 29 | position: absolute; 30 | width: 30%; 31 | height: 100%; 32 | overflow: auto; } 33 | .two-pane-app .bottom .left .item { 34 | height: 4em; 35 | border-bottom: 0.0625em solid rgba(0, 0, 0, 0.1); 36 | cursor: pointer; } 37 | .two-pane-app .bottom .left .item:hover { 38 | background: rgba(0, 0, 0, 0.1); 39 | border-bottom: 0.0625em solid rgba(0, 0, 0, 0); } 40 | .two-pane-app .bottom .left .item:last-child { 41 | border-bottom: 0; } 42 | .two-pane-app .bottom .right { 43 | position: absolute; 44 | width: 70%; 45 | right: 0; 46 | height: 100%; 47 | overflow: auto; 48 | padding: 1.25em; } 49 | .two-pane-app .title { 50 | display: -moz-inline-stack; 51 | display: inline-block; 52 | vertical-align: middle; 53 | *vertical-align: auto; 54 | zoom: 1; 55 | *display: inline; 56 | background: rgba(0, 0, 0, 0.1); 57 | width: 10em; 58 | height: 1em; 59 | margin-bottom: 1.25em; } 60 | -------------------------------------------------------------------------------- /potions/two-pane-app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Two Pane App — Potion — Magic of CSS — Adam Schwartz 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |

55 |

56 |
57 |
58 |
59 | 60 | -------------------------------------------------------------------------------- /potions/two-pane-app/sass/two-pane-app.sass: -------------------------------------------------------------------------------- 1 | @import compass/css3 2 | 3 | html, body 4 | height: 100% 5 | overflow: hidden 6 | 7 | .two-pane-app 8 | position: absolute 9 | top: 0 10 | left: 0 11 | bottom: 0 12 | right: 0 13 | 14 | *, *::after, *::before 15 | box-sizing: border-box 16 | 17 | .top 18 | position: absolute 19 | height: 3.75em 20 | padding: 1.25em 21 | line-height: 2.5em 22 | width: 100% 23 | border-bottom: .0625em solid rgba(0, 0, 0, .1) 24 | 25 | .bottom 26 | position: absolute 27 | top: 3.75em 28 | bottom: 0 29 | width: 100% 30 | 31 | .left 32 | border-right: .0625em solid rgba(0, 0, 0, .1) 33 | position: absolute 34 | width: 30% 35 | height: 100% 36 | overflow: auto 37 | 38 | .item 39 | height: 4em 40 | border-bottom: .0625em solid rgba(0, 0, 0, .1) 41 | cursor: pointer 42 | 43 | &:hover 44 | background: rgba(0, 0, 0, .1) 45 | border-bottom: .0625em solid rgba(0, 0, 0, 0) 46 | 47 | &:last-child 48 | border-bottom: 0 49 | 50 | .right 51 | position: absolute 52 | width: 70% 53 | right: 0 54 | height: 100% 55 | overflow: auto 56 | padding: 1.25em 57 | 58 | .title 59 | +inline-block 60 | background: rgba(0, 0, 0, .1) 61 | width: 10em 62 | height: 1em 63 | margin-bottom: 1.25em -------------------------------------------------------------------------------- /sass/_colors.sass: -------------------------------------------------------------------------------- 1 | $purple: #6335e6 2 | $blue: #0085ae 3 | $green: #8ebd14 4 | $yellow: #ffc359 5 | $orange: #ff716a 6 | $red: #ff3283 7 | 8 | $selectionColor: currentColor 9 | -------------------------------------------------------------------------------- /sass/_rainbow.sass: -------------------------------------------------------------------------------- 1 | @import compass/css3 2 | $supported-browsers: reject(browsers(), "android", "android-chrome", "android-firefox", "blackberry", "chrome", "firefox", "ie", "ie-mobile", "ios-safari", "opera", "opera-mini", "opera-mobile", "safari") 3 | 4 | @import colors 5 | 6 | =rainbow($rainbowSize, $bandWidth, $reverse: false) 7 | transform: rotateZ(90deg) 8 | transform-origin: 50% 100% 9 | height: $rainbowSize / 2 10 | width: $rainbowSize 11 | overflow: hidden 12 | position: relative 13 | 14 | .bands 15 | position: absolute 16 | top: 0 17 | left: 0 18 | height: $rainbowSize / 2 19 | width: $rainbowSize 20 | overflow: hidden 21 | 22 | &::before 23 | box-shadow: inset 0 0 0 ($bandWidth * 6) $purple, inset 0 0 0 ($bandWidth * 5) $blue, inset 0 0 0 ($bandWidth * 4) $green, inset 0 0 0 ($bandWidth * 3) $yellow, inset 0 0 0 ($bandWidth * 2) $orange, inset 0 0 0 ($bandWidth * 1) $red 24 | @if $reverse 25 | box-shadow: inset 0 0 0 ($bandWidth * 6) $red, inset 0 0 0 ($bandWidth * 5) $orange, inset 0 0 0 ($bandWidth * 4) $yellow, inset 0 0 0 ($bandWidth * 3) $green, inset 0 0 0 ($bandWidth * 2) $blue, inset 0 0 0 ($bandWidth * 1) $purple 26 | 27 | box-shadow: inset 0 0 0 ($bandWidth * 1) $red, inset 0 0 0 ($bandWidth * 2) $orange, inset 0 0 0 ($bandWidth * 3) $yellow, inset 0 0 0 ($bandWidth * 4) $green, inset 0 0 0 ($bandWidth * 5) $blue, inset 0 0 0 ($bandWidth * 6) $purple 28 | @if $reverse 29 | box-shadow: inset 0 0 0 ($bandWidth * 1) $purple, inset 0 0 0 ($bandWidth * 2) $blue, inset 0 0 0 ($bandWidth * 3) $green, inset 0 0 0 ($bandWidth * 4) $yellow, inset 0 0 0 ($bandWidth * 5) $orange, inset 0 0 0 ($bandWidth * 6) $red 30 | 31 | +border-radius(50%) 32 | content: "" 33 | display: block 34 | position: absolute 35 | margin: auto 36 | left: 0 37 | right: 0 38 | bottom: - ($rainbowSize / 2) 39 | height: $rainbowSize 40 | width: $rainbowSize 41 | -------------------------------------------------------------------------------- /sass/_variables.sass: -------------------------------------------------------------------------------- 1 | $chapterWidth: 36rem 2 | $chapterBreakPoint: $chapterWidth + (2 * 1rem) 3 | $chapterBreakPointLarge: $chapterWidth + (2 * 4rem) 4 | $chapterBreakPointXLarge: $chapterWidth * 2 -------------------------------------------------------------------------------- /sass/base.sass: -------------------------------------------------------------------------------- 1 | @import compass/css3 2 | @import compass/utilities/general/clearfix 3 | 4 | @import colors 5 | @import variables 6 | 7 | @import social 8 | 9 | *, *::after, *::before 10 | box-sizing: border-box 11 | 12 | ::-moz-selection 13 | text-shadow: none 14 | background: $selectionColor 15 | color: #fff 16 | 17 | ::selection 18 | text-shadow: none 19 | background: $selectionColor 20 | color: #fff 21 | 22 | html 23 | font-size: 16px 24 | --purple: #{$purple} 25 | --blue: #{$blue} 26 | --green: #{$green} 27 | --yellow: #{$yellow} 28 | --orange: #{$orange} 29 | --red: #{$red} 30 | 31 | @media (min-width: $chapterBreakPointXLarge) 32 | font-size: 20px 33 | 34 | body 35 | font-family: Avenir, "Helvetica Neue", sans-serif 36 | background: #fff 37 | color: #000 38 | margin: 0 39 | text-rendering: optimizeLegibility 40 | -webkit-font-smoothing: antialiased 41 | -webkit-text-size-adjust: 100% 42 | 43 | h1, h2, h3, h4, h5, h6 44 | font-weight: 600 45 | 46 | a 47 | color: $blue 48 | 49 | &:visited 50 | color: $purple 51 | 52 | .clearfix 53 | +pie-clearfix -------------------------------------------------------------------------------- /sass/eager.sass: -------------------------------------------------------------------------------- 1 | @import compass/css3 2 | @import compass/utilities/general/clearfix 3 | 4 | @import colors 5 | 6 | .eager 7 | display: block 8 | text-align: center 9 | padding-left: 1em 10 | padding-right: 1em 11 | 12 | .eager-outer 13 | +border-radius(.3125em) 14 | padding: 4px 15 | background-color: $red 16 | background-image: linear-gradient(90deg, $red 0%, $red 17%, $orange 17%, $orange 34%, $yellow 34%, $yellow 51%, $green 51%, $green 67%, $blue 67%, $blue 83%, $purple 83%, $purple 100%) 17 | display: inline-block 18 | max-width: 100% 19 | width: 26em 20 | 21 | .eager-inner 22 | +border-radius(.1875em) 23 | background-color: #fff 24 | background: linear-gradient(rgba(255, 255, 255, 0.91), #fff) 25 | padding: 1.125em 26 | 27 | .smart-underlined 28 | color: inherit 29 | text-decoration: none 30 | background: linear-gradient(#fff, #fff), linear-gradient(#fff, #fff), linear-gradient(#333332, #333332) 31 | background-size: .05em 1px, .05em 1px, 1px 1px 32 | background-repeat: no-repeat, no-repeat, repeat-x 33 | 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 34 | background-position-y: 87%, 87%, 87% 35 | background-position-x: 0%, 100%, 0% 36 | 37 | &::selection 38 | text-shadow: 0.03em 0 $selectionColor, -0.03em 0 $selectionColor, 0 0.03em $selectionColor, 0 -0.03em $selectionColor, 0.06em 0 $selectionColor, -0.06em 0 $selectionColor, 0.09em 0 $selectionColor, -0.09em 0 $selectionColor, 0.12em 0 $selectionColor, -0.12em 0 $selectionColor, 0.15em 0 $selectionColor, -0.15em 0 $selectionColor 39 | background: $selectionColor 40 | 41 | &::-moz-selection 42 | text-shadow: 0.03em 0 $selectionColor, -0.03em 0 $selectionColor, 0 0.03em $selectionColor, 0 -0.03em $selectionColor, 0.06em 0 $selectionColor, -0.06em 0 $selectionColor, 0.09em 0 $selectionColor, -0.09em 0 $selectionColor, 0.12em 0 $selectionColor, -0.12em 0 $selectionColor, 0.15em 0 $selectionColor, -0.15em 0 $selectionColor 43 | background: $selectionColor 44 | 45 | h1 46 | font-size: 1em 47 | margin: 0 0 1em 48 | 49 | p 50 | margin: 1em 0 0 51 | 52 | &.small 53 | font-size: .8em 54 | padding: 0 2em 55 | line-height: 1.33em 56 | margin-bottom: -.2em 57 | 58 | a.eager-button 59 | text-decoration: none 60 | display: block 61 | cursor: pointer 62 | +border-radius(10em) 63 | font-weight: bold 64 | padding: .7em 1.2em 65 | background: #4039a5 66 | color: #fff 67 | -------------------------------------------------------------------------------- /sass/home.sass: -------------------------------------------------------------------------------- 1 | @import compass/css3 2 | @import compass/utilities/general/clearfix 3 | 4 | @import rainbow 5 | @import colors 6 | @import variables 7 | 8 | body 9 | margin: 0 10 | 11 | @media (min-width: $chapterBreakPointLarge) 12 | margin: 8em 0 13 | 14 | .page 15 | text-align: center 16 | padding: 2em 0 17 | 18 | @media (min-width: $chapterBreakPointLarge) 19 | padding: 0 20 | 21 | .separator 22 | height: 2.5em 23 | 24 | @media (min-width: $chapterBreakPointLarge) 25 | height: 10em 26 | 27 | p.author 28 | font-size: 1.4rem 29 | margin-top: 2em 30 | letter-spacing: .05em 31 | padding-left: .43em 32 | color: #888 33 | font-weight: 300 34 | 35 | a 36 | text-decoration: none 37 | color: inherit 38 | 39 | .share 40 | margin-top: -.7rem 41 | margin-bottom: .7rem 42 | padding-left: .6rem 43 | font-size: 0 44 | 45 | iframe 46 | +inline-block 47 | background: #eee 48 | border-radius: 5px 49 | margin-left: auto 50 | margin-right: auto 51 | border: 0 52 | height: 2.4rem 53 | width: 13.6rem 54 | height: 1.6rem 55 | opacity: .8 56 | 57 | &:hover 58 | opacity: 1 59 | 60 | &.github 61 | width: 8rem 62 | 63 | h2 64 | font-weight: 300 65 | text-transform: uppercase 66 | letter-spacing: .4em 67 | font-size: 1.375em 68 | line-height: 1 69 | position: relative 70 | margin: 2.5rem 0 71 | color: #aaa 72 | padding: 0 1rem 73 | 74 | span 75 | margin-right: -.4em 76 | 77 | @media (min-width: $chapterBreakPointLarge) 78 | margin: 5rem 0 79 | 80 | ol.chapters 81 | list-style-type: none 82 | margin-left: 0 83 | 84 | > li 85 | +pie-clearfix 86 | clear: left 87 | counter-increment: chaptersCounter 88 | 89 | &::before 90 | +inline-block 91 | content: counter(chaptersCounter) " " 92 | margin-bottom: .875rem 93 | color: #aaa 94 | text-align: center 95 | width: 1em 96 | margin-right: .625em 97 | font-weight: 300 98 | float: left 99 | 100 | &.coming-soon 101 | 102 | &::before 103 | opacity: 0 104 | 105 | a 106 | font-size: .8em 107 | margin-top: .2em 108 | opacity: .4 109 | 110 | &:first-child 111 | counter-reset: chaptersCounter 112 | 113 | a 114 | +inline-block 115 | margin-bottom: 1rem 116 | 117 | ol.chapters, ul.potions, .preface-link 118 | font-weight: 300 119 | letter-spacing: .01em 120 | margin-right: -.01em 121 | font-size: 1.25em 122 | line-height: 1 123 | position: relative 124 | width: 14em 125 | max-width: 100% 126 | text-align: left 127 | margin: 0 auto 128 | padding: 0 1rem 129 | 130 | @media (min-width: $chapterBreakPointLarge) 131 | font-size: 1.75rem 132 | 133 | @media (min-width: $chapterBreakPointXLarge) 134 | font-size: 2rem 135 | 136 | a 137 | color: inherit 138 | text-decoration: none 139 | white-space: nowrap 140 | 141 | html[data-user-agent*="Chrome"] & 142 | 143 | &:hover span 144 | background: linear-gradient(#fff, #fff), linear-gradient(#fff, #fff), linear-gradient(#464646, #464646) 145 | background-size: .05em 2px, .05em 2px, 2px 2px 146 | background-repeat: no-repeat, no-repeat, repeat-x 147 | text-shadow: .03em 0 #fff, -.03em 0 #fff, 0 .03em #fff, 0 -.03em #fff, .06em 0 #fff, -.06em 0 #fff, .09em 0 #fff, -.09em 0 #fff 148 | background-position-y: 88%, 88%, 88% 149 | background-position-x: 0%, 100%, 0% 150 | 151 | &::selection 152 | text-shadow: .03em 0 $selectionColor, -.03em 0 $selectionColor, 0 .03em $selectionColor, 0 -.03em $selectionColor, .06em 0 $selectionColor, -.06em 0 $selectionColor, .09em 0 $selectionColor, -.09em 0 $selectionColor 153 | background: $selectionColor 154 | 155 | &::-moz-selection 156 | text-shadow: .03em 0 $selectionColor, -.03em 0 $selectionColor, 0 .03em $selectionColor, 0 -.03em $selectionColor, .06em 0 $selectionColor, -.06em 0 $selectionColor, .09em 0 $selectionColor, -.09em 0 $selectionColor 157 | background: $selectionColor 158 | 159 | &[data-starts-with="T"] 160 | background-size: .15em 2px, .05em 2px, 2px 2px 161 | 162 | ul.potions, .preface-link 163 | list-style: none 164 | text-align: center 165 | 166 | li 167 | margin-bottom: .5em 168 | 169 | // Loading animation 170 | 171 | .logo.animated 172 | 173 | .the-magic-of 174 | transition: opacity 800ms 1300ms ease-in-out 175 | opacity: 0 176 | 177 | .trigger-pageload-animations & 178 | opacity: 1 179 | 180 | .css-rainbow 181 | 182 | .rainbow 183 | -webkit-backface-visibility: hidden 184 | 185 | .css-rainbow-c .rainbow 186 | transition: transform 800ms 0ms ease-in-out 187 | transform: rotateZ(90deg) 188 | 189 | .trigger-pageload-animations & 190 | transform: rotateZ(-90deg) 191 | 192 | .css-rainbow-s-1 193 | 194 | .bottom-half .rainbow 195 | transition: transform 400ms 600ms ease-in 196 | transform: rotateZ(270deg) 197 | 198 | .trigger-pageload-animations & 199 | transform: rotateZ(90deg) 200 | 201 | .top-half .rainbow 202 | transition: transform 400ms 1000ms ease-out 203 | transform: rotateZ(90deg) 204 | 205 | .trigger-pageload-animations & 206 | transform: rotateZ(270deg) 207 | 208 | .css-rainbow-s-2 209 | 210 | .bottom-half .rainbow 211 | transition: transform 400ms 800ms ease-in 212 | transform: rotateZ(270deg) 213 | 214 | .trigger-pageload-animations & 215 | transform: rotateZ(90deg) 216 | 217 | .top-half .rainbow 218 | transition: transform 400ms 1200ms ease-out 219 | transform: rotateZ(90deg) 220 | 221 | .trigger-pageload-animations & 222 | transform: rotateZ(270deg) 223 | 224 | .page-inner > *:not(.logo) 225 | transition: opacity 800ms 1300ms ease-in-out 226 | opacity: 0 227 | 228 | .trigger-pageload-animations & 229 | opacity: 1 230 | 231 | .window-has-been-scrolled &, .has-been-here-before & 232 | transition: none 233 | 234 | .trigger-pageload-animations.trigger-pageload-animations-3s .logo.animated:hover 235 | 236 | .css-rainbow 237 | 238 | .css-rainbow-c .rainbow 239 | transition: transform 800ms 1200ms ease-in-out 240 | transform: rotateZ(90deg) 241 | 242 | .css-rainbow-s-1 243 | 244 | .bottom-half .rainbow 245 | transition: transform 400ms 1000ms ease-out 246 | transform: rotateZ(270deg) 247 | 248 | .top-half .rainbow 249 | transition: transform 400ms 600ms ease-in 250 | transform: rotateZ(90deg) 251 | 252 | .css-rainbow-s-2 253 | 254 | .bottom-half .rainbow 255 | transition: transform 400ms 400ms ease-out 256 | transform: rotateZ(270deg) 257 | 258 | .top-half .rainbow 259 | transition: transform 400ms 0ms ease-in 260 | transform: rotateZ(90deg) 261 | -------------------------------------------------------------------------------- /sass/logo.sass: -------------------------------------------------------------------------------- 1 | @import compass/css3 2 | 3 | @import rainbow 4 | 5 | .logo 6 | display: block 7 | text-decoration: none 8 | font-size: .75rem 9 | height: 10.875em 10 | width: 18.4375em 11 | margin: 0 auto 12 | max-width: 100% 13 | text-align: center 14 | 15 | .the-magic-of 16 | font-weight: 300 17 | text-transform: uppercase 18 | letter-spacing: .4em 19 | font-size: 1.375em 20 | height: 1em 21 | line-height: 1 22 | margin: 0 0 1em 23 | overflow: hidden 24 | position: relative 25 | left: .2em 26 | margin-bottom: 1.27272727em 27 | color: #aaa 28 | 29 | .css-rainbow 30 | max-width: 100% 31 | white-space: nowrap 32 | 33 | .css-letter 34 | +inline-block 35 | 36 | .css-rainbow-c 37 | position: relative 38 | overflow: hidden 39 | width: 3.825em 40 | height: 7.75em 41 | margin-right: 3.175em 42 | 43 | .rainbow 44 | +rainbow(7.75em, .5625em) 45 | transform: rotateZ(-90deg) 46 | position: absolute 47 | 48 | .css-rainbow-s 49 | transform: translate3d(0, 0, 0) rotateZ(22.5deg) 50 | width: 5em 51 | height: 7.75em 52 | 53 | // Damn rounding 54 | position: relative 55 | top: .15em 56 | 57 | .rainbow 58 | position: absolute 59 | 60 | .top-half 61 | position: absolute 62 | overflow: hidden 63 | width: 2.5em 64 | height: 5em 65 | 66 | .rainbow 67 | +rainbow(5em, .375em) 68 | transform: rotateZ(-90deg) 69 | 70 | .bottom-half 71 | position: absolute 72 | overflow: hidden 73 | width: 2.5em 74 | height: 5em 75 | top: 2.75em 76 | left: 2.5em 77 | 78 | // Damn rounding 79 | left: 2.45em 80 | 81 | .rainbow 82 | +rainbow(5em, .375em, true) 83 | transform: rotateZ(90deg) 84 | left: -2.5em 85 | 86 | &.css-rainbow-s-1 87 | margin-right: 1.875em 88 | 89 | &.css-rainbow-s-2 90 | margin-right: -.4375em 91 | 92 | @media (min-width: 48em) 93 | font-size: 1rem -------------------------------------------------------------------------------- /sass/potions.sass: -------------------------------------------------------------------------------- 1 | @import compass/css3 2 | @import compass/utilities/general/clearfix 3 | 4 | .mock-paragraph b 5 | +inline-block 6 | background: rgba(0, 0, 0, .1) 7 | width: 3.125em 8 | height: .5em 9 | margin-right: .3125em 10 | margin-bottom: .3125em 11 | 12 | &:nth-last-child(4n+1) 13 | width: 4.5625em 14 | 15 | &:nth-last-child(10n+1) 16 | width: .875em 17 | 18 | &:nth-last-child(9n+1) 19 | width: 5em -------------------------------------------------------------------------------- /sass/social.sass: -------------------------------------------------------------------------------- 1 | @font-face 2 | font-family: "social-icons" 3 | src: url(data:application/x-font-woff;charset=utf-8;base64,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) format('woff') 4 | font-weight: normal 5 | font-style: normal --------------------------------------------------------------------------------