The response has been limited to 50k tokens of the smallest files in the repo. You can remove this limitation by removing the max tokens filter.
├── .eslintrc
├── .gitignore
├── .jshintrc
├── LICENSE
├── README.md
├── assets
    ├── css
    │   ├── base
    │   │   ├── custom-media.css
    │   │   ├── elements.css
    │   │   └── variables.css
    │   ├── components
    │   │   ├── aligner.css
    │   │   ├── browser.css
    │   │   ├── button.css
    │   │   ├── container.css
    │   │   ├── demo.css
    │   │   ├── error.css
    │   │   ├── feature.css
    │   │   ├── footer.css
    │   │   ├── grid.css
    │   │   ├── header.css
    │   │   ├── holy-grail.css
    │   │   ├── image.css
    │   │   ├── input-add-on.css
    │   │   ├── media.css
    │   │   ├── notice.css
    │   │   ├── section.css
    │   │   └── site.css
    │   ├── main.css
    │   ├── utils
    │   │   ├── compat.css
    │   │   ├── media.css
    │   │   └── size.css
    │   └── vendor
    │   │   ├── font-awesome-extensions.css
    │   │   ├── highlight.css
    │   │   └── twitter.css
    ├── images
    │   ├── browser-logos.jpg
    │   ├── grids.jpg
    │   ├── holy-grail.jpg
    │   ├── input-add-ons.jpg
    │   ├── kitten.jpg
    │   ├── media-object.jpg
    │   ├── sticky-footer.jpg
    │   └── vertical-centering.jpg
    └── main.js
├── config.json
├── demos
    ├── grids.md
    ├── holy-grail.md
    ├── input-add-ons.md
    ├── media-object.md
    ├── sticky-footer.md
    └── vertical-centering.md
├── gulpfile.js
├── index.html
├── package-lock.json
├── package.json
├── rollup.config.js
└── templates
    ├── default.html
    ├── footer.html
    ├── head.html
    ├── header.html
    ├── holy-grail.html
    ├── home.html
    └── scripts.html


/.eslintrc:
--------------------------------------------------------------------------------
 1 | {
 2 |   "parser": "babel-eslint",
 3 |   "env": {
 4 |     "browser": true,
 5 |     "es6": true,
 6 |     "node": true,
 7 |     "mocha": true
 8 |   },
 9 |   "globals": {
10 |     "browser": false
11 |   },
12 |   "extends": [
13 |     "eslint:recommended"
14 |   ]
15 | }
16 | 


--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
 1 | # OS or Editor folders
 2 | .DS_Store
 3 | 
 4 | # npm/yarn files
 5 | node_modules
 6 | *.log
 7 | *.lock
 8 | 
 9 | # Static site output
10 | _tmp/
11 | solved-by-flexbox/
12 | 


--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 |   "browser": true,
3 |   "boss": true,
4 |   "esnext": true,
5 |   "expr": true,
6 |   "node": true,
7 |   "quotmark": "single"
8 | }
9 | 


--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
 1 | Copyright (c) 2015 Philip Walton
 2 | 
 3 | Permission is hereby granted, free of charge, to any person
 4 | obtaining a copy of this software and associated documentation
 5 | files (the "Software"), to deal in the Software without
 6 | restriction, including without limitation the rights to use,
 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell
 8 | copies of the Software, and to permit persons to whom the
 9 | Software is furnished to do so, subject to the following
10 | conditions:
11 | 
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 | 
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.
23 | 


--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
 1 | # Solved by Flexbox
 2 | 
 3 | A showcase of problems once hard or impossible to solve with CSS alone, now made trivially easy with Flexbox.
 4 | 
 5 | [View Site](https://philipwalton.github.io/solved-by-flexbox/)
 6 | 
 7 | ## Viewing the Site Locally
 8 | 
 9 | The Solved by Flexbox site can be built with [Node.js](http://nodejs.org/). If you have Node.js installed on your system, you can run the following commands to build and serve a local copy.
10 | 
11 | ```sh
12 | # Clone the git repository and cd into the cloned directory.
13 | git clone https://github.com/philipwalton/solved-by-flexbox.git
14 | cd solved-by-flexbox
15 | 
16 | # Install the dependencies
17 | npm install
18 | 
19 | # Build and serve the site at http://localhost:4000
20 | npm start
21 | ```
22 | 
23 | This starts up a local server on port 4000. To view the site in your browser, navigate to [http://localhost:4000](http://localhost:4000). If you want to use a different port, you can pass the port number as an argument to `npm start`:
24 | 
25 | ```sh
26 | npm start -- -p 8080
27 | ```
28 | 
29 | In addition to building the site and serving it locally, this will also listen for any changes and rebuild the site as needed. This allows you to play around with the code, refresh the browser, and see your changes instantly.
30 | 
31 | ## Translations
32 | 
33 | The following translations have been graciously provided by the community:
34 | 
35 | * [Chinese](https://hufan-akari.github.io/solved-by-flexbox/)
36 | * [Japanese](http://hashrock.github.io/solved-by-flexbox-ja/)
37 | * [Korean](https://hyunseob.github.io/solved-by-flexbox-kr/)
38 | 
39 | Please note that translations are unofficial and may be inaccurate or out of date. To submit your own translation, please submit a [pull request](https://github.com/philipwalton/solved-by-flexbox/pull/new/master) or [open an issue](https://github.com/philipwalton/solved-by-flexbox/issues/new) and link to your translated content.
40 | 


--------------------------------------------------------------------------------
/assets/css/base/custom-media.css:
--------------------------------------------------------------------------------
1 | @custom-media --break-sm (min-width: 384px);
2 | @custom-media --break-md (min-width: 576px);
3 | @custom-media --break-lg (min-width: 768px);
4 | 
5 | @custom-media --high-dppx (-webkit-min-device-pixel-ratio: 1.5),
6 |     (min-resolution: 144dpi), (min-resolution: 1.5dppx);
7 | 


--------------------------------------------------------------------------------
/assets/css/base/elements.css:
--------------------------------------------------------------------------------
 1 | *,
 2 | *::after,
 3 | *::before {
 4 |   box-sizing: border-box;
 5 | }
 6 | 
 7 | html {
 8 |   height: 100%;
 9 |   color: hsl(0,0%,25%);
10 |   font: 400 1em/1.4 'Open Sans', sans-serif;
11 |   text-rendering: optimizeLegibility;
12 | }
13 | @media (--high-dppx) {
14 |   html {
15 |     font-weight: 300;
16 |   }
17 | }
18 | 
19 | h1 {
20 |   font-weight: 300;
21 |   font-size: 2em;
22 |   -webkit-font-kerning: normal;
23 |   letter-spacing: -.015em;
24 |   line-height: 1;
25 |   margin: .25em 0 .75em;
26 | }
27 | @media (--break-lg) {
28 |   h1 {
29 |     font-size: 2.5em;
30 |     margin: .5em 0 1em;
31 |   }
32 | }
33 | 
34 | 
35 | h2 {
36 |   font-size: 1.333em;
37 |   font-weight: 600;
38 |   margin: 0 0 calc(1.5em/1.333);
39 | }
40 | 
41 | h3 {
42 |   font-size: 1em;
43 |   font-weight: 600;
44 |   margin: 0 0 1.5em;
45 | }
46 | 
47 | p,
48 | pre {
49 |   margin: 0 0 1.5em;
50 | }
51 | 
52 | code,
53 | pre {
54 |   font-family: 'Menlo', 'Monaco', monospace;
55 | }
56 | 
57 | code {
58 |   font-size: .9em;
59 |   font-weight: normal;
60 |   color: #000;
61 | }
62 | 
63 | pre > code {
64 |   font: inherit;
65 |   color: inherit;
66 | }
67 | 
68 | a {
69 |   border-bottom: 1px dashed hsla(150, 45%, 50%, 0.5);
70 |   color: hsl(150, 45%, 50%);
71 |   text-decoration: none;
72 | }
73 | a:focus,
74 | a:hover {
75 |   border-bottom: 1px solid hsl(150, 45%, 50%);
76 | }
77 | 
78 | ol,
79 | ul {
80 |   list-style: square;
81 |   margin: 0 0 1.5em;
82 |   padding: 0 0 0 1.5em;
83 | }
84 | 
85 | li {
86 |   margin-bottom: 0.333em;
87 | }
88 | 
89 | 
90 | figure {
91 |   margin: 0;
92 | }
93 | 
94 | strong {
95 |   font-weight: 600;
96 | }
97 | 


--------------------------------------------------------------------------------
/assets/css/base/variables.css:
--------------------------------------------------------------------------------
1 | :root {
2 |   --space: 1.5em;
3 |   --space-lg: 2em;
4 |   --bg-color: hsl(150, 45%, 50%);
5 | }
6 | 


--------------------------------------------------------------------------------
/assets/css/components/aligner.css:
--------------------------------------------------------------------------------
 1 | .Aligner {
 2 |   display: flex;
 3 |   align-items: center;
 4 |   min-height: 24em;
 5 |   justify-content: center;
 6 | }
 7 | 
 8 | .Aligner-item {
 9 |   flex: 1;
10 | }
11 | 
12 | .Aligner-item--top {
13 |   align-self: flex-start;
14 | }
15 | 
16 | .Aligner-item--bottom {
17 |   align-self: flex-end;
18 | }
19 | 
20 | .Aligner-item--fixed {
21 |   flex: none;
22 |   max-width: 50%;
23 | }
24 | 


--------------------------------------------------------------------------------
/assets/css/components/browser.css:
--------------------------------------------------------------------------------
 1 | .Browser {
 2 |   font-size: .8em;
 3 |   text-align: center;
 4 | }
 5 | 
 6 | .Browser-image {
 7 |   height: 64px;
 8 |   width: 64px;
 9 |   margin: 0 0.5em 0.5em;
10 |   background: url('images/browser-logos.jpg') no-repeat 0 0;
11 |   background-size: auto 100%;
12 | }
13 | 
14 | .Browser--chrome > .Browser-image {
15 |   background-position: 0 0;
16 | }
17 | 
18 | .Browser--opera > .Browser-image {
19 |   background-position: -64px 0;
20 | }
21 | 
22 | .Browser--firefox > .Browser-image {
23 |   background-position: -128px 0;
24 | }
25 | 
26 | .Browser--safari > .Browser-image {
27 |   background-position: -192px 0;
28 | }
29 | 
30 | .Browser--ie > .Browser-image {
31 |   background-position: -256px 0;
32 | }
33 | 
34 | .Browser--edge > .Browser-image {
35 |   background-position: -320px 0;
36 | }
37 | 
38 | 


--------------------------------------------------------------------------------
/assets/css/components/button.css:
--------------------------------------------------------------------------------
 1 | .Button {
 2 |   transition: background-color 0.2s;
 3 |   display: inline-block;
 4 |   padding: 0.6em 1em;
 5 |   background: hsla(31, 15%, 50%, 0.15);
 6 |   color: inherit;
 7 |   border: 0;
 8 |   border-radius: 2px;
 9 |   cursor: pointer;
10 |   font-size: 0.8125em;
11 |   font-weight: 300;
12 |   line-height: normal;
13 |   text-decoration: none;
14 |   white-space: nowrap;
15 | }
16 | .Button:focus {
17 |   outline: thin dotted #666;
18 |   text-decoration: none;
19 | }
20 | .Button:active,
21 | .Button:focus,
22 | .Button:hover {
23 |   border: 0;
24 |   background: hsla(31, 15%, 50%, 0.25);
25 |   text-decoration: none;
26 | }
27 | 
28 | .Button--action {
29 |   background-color: hsl(150, 45%, 50%);
30 |   color: #fff;
31 | }
32 | .Button--action:active,
33 | .Button--action:focus,
34 | .Button--action:hover {
35 |   background-color: hsl(150, 45%, 40%);
36 | }
37 | 
38 | .Button--wide {
39 |   padding-right: 1.5em;
40 |   padding-left: 1.5em;
41 | }
42 | 


--------------------------------------------------------------------------------
/assets/css/components/container.css:
--------------------------------------------------------------------------------
1 | .Container {
2 |   max-width: 50em;
3 |   margin: 0 auto;
4 | }
5 | 


--------------------------------------------------------------------------------
/assets/css/components/demo.css:
--------------------------------------------------------------------------------
 1 | .Demo {
 2 |   width: 100%;
 3 |   padding: .8em 1em 0;
 4 |   background: hsla(31, 15%, 50%, 0.1);
 5 |   border-radius: 3px;
 6 | }
 7 | .Demo::after {
 8 |   content: '\00a0'; /*   */
 9 |   display: block;
10 |   margin-top: 1em;
11 |   height: 0px;
12 |   visibility: hidden;
13 | }
14 | 
15 | .Demo--spaced {
16 |   margin-bottom: var(--space);
17 | }
18 | 


--------------------------------------------------------------------------------
/assets/css/components/error.css:
--------------------------------------------------------------------------------
1 | .Error {
2 |   padding: 1em 1.5em;
3 |   background: #c00;
4 |   color: #fff;
5 |   font-weight: 700;
6 |   text-align: center;
7 | }
8 | 


--------------------------------------------------------------------------------
/assets/css/components/feature.css:
--------------------------------------------------------------------------------
 1 | .Feature {
 2 | 
 3 | }
 4 | 
 5 | .Feature-figure {
 6 |   margin-bottom: 0.75em;
 7 |   border: 1px solid hsl(0, 0%, 85%);
 8 |   transition: border-color 0.2s;
 9 | }
10 | 
11 | .Feature-image {
12 |   display: block;
13 |   max-width: 100%;
14 |   height: auto;
15 |   border: 5px solid hsl(0, 100%, 100%);
16 | }
17 | 
18 | .Feature-title {
19 |   margin: 0 0 0.5em;
20 |   color: hsl(0, 0%, 25%);
21 |   text-align: center;
22 |   transition: color 0.1s;
23 | }
24 | 
25 | .Feature-description {
26 |   margin: 0 0.75em;
27 |   font-size: 0.8em;
28 | }
29 | 
30 | .Feature a:active .Feature-figure,
31 | .Feature a:focus .Feature-figure,
32 | .Feature a:hover .Feature-figure {
33 |   border-color: hsl(150, 45%, 50%);
34 | }
35 | 
36 | .Feature a:active .Feature-title,
37 | .Feature a:focus .Feature-title,
38 | .Feature a:hover .Feature-title {
39 |   color: hsl(150, 45%, 50%);
40 | }
41 | 


--------------------------------------------------------------------------------
/assets/css/components/footer.css:
--------------------------------------------------------------------------------
 1 | .Footer {
 2 |   padding: 1.5rem 1.5rem;
 3 |   background: hsl(0, 0%, 25%);
 4 |   color: hsl(0, 0%, 60%);
 5 |   font-size: 0.85em;
 6 |   overflow-x: hidden;
 7 |   text-align: center;
 8 | }
 9 | 
10 | .Footer a {
11 |   padding-bottom: 1px;
12 |   border: 0;
13 |   color:  hsl(0, 0%, 90%);
14 | }
15 | .Footer a:focus,
16 | .Footer a:active,
17 | .Footer a:hover {
18 |   color: #fff;
19 |   text-decoration: underline;
20 | }
21 | 
22 | .Footer-credits {
23 |   margin: 0;
24 |   padding: 0;
25 | }
26 | 
27 | .Footer-credit {
28 |   display: block;
29 |   margin: 0;
30 | }
31 | 
32 | .Footer-creditSeparator {
33 |   display: none;
34 | }
35 | 
36 | /* The GitHub button updates the link to be a span */
37 | .Footer-social > span {
38 |   margin-right: 1em;
39 | }
40 | 
41 | /* If loading the social button fails */
42 | .Footer-social a,
43 | .Footer-social iframe {
44 |   display: inline-block;
45 |   margin: 0 0 1em;
46 |   vertical-align: top;
47 | }
48 | 
49 | @media (--break-md) {
50 |   .Footer-credit {
51 |     display: inline-block;
52 |     margin: 0 0.25em;
53 |   }
54 |   .Footer-creditSeparator {
55 |     display: inline-block;
56 |     padding: 0 0.25em;
57 |   }
58 | }
59 | 


--------------------------------------------------------------------------------
/assets/css/components/grid.css:
--------------------------------------------------------------------------------
  1 | .Grid {
  2 |   display: flex;
  3 |   flex-wrap: wrap;
  4 |   list-style: none;
  5 |   margin: 0;
  6 |   padding: 0;
  7 | }
  8 | 
  9 | .Grid-cell {
 10 |   flex: 1;
 11 | }
 12 | 
 13 | .Grid--flexCells > .Grid-cell {
 14 |   display: flex;
 15 | }
 16 | 
 17 | .Grid--top {
 18 |   align-items: flex-start;
 19 | }
 20 | 
 21 | .Grid--bottom {
 22 |   align-items: flex-end;
 23 | }
 24 | 
 25 | .Grid--center {
 26 |   align-items: center;
 27 | }
 28 | 
 29 | .Grid--justifyCenter {
 30 |   justify-content: center;
 31 | }
 32 | 
 33 | .Grid-cell--top {
 34 |   align-self: flex-start;
 35 | }
 36 | 
 37 | .Grid-cell--bottom {
 38 |   align-self: flex-end;
 39 | }
 40 | 
 41 | .Grid-cell--center {
 42 |   align-self: center;
 43 | }
 44 | 
 45 | .Grid-cell--autoSize {
 46 |   flex: none;
 47 | }
 48 | 
 49 | .Grid--fit > .Grid-cell {
 50 |   flex: 1;
 51 | }
 52 | 
 53 | .Grid--full > .Grid-cell {
 54 |   flex: 0 0 100%;
 55 | }
 56 | 
 57 | .Grid--1of2 > .Grid-cell {
 58 |   flex: 0 0 50%;
 59 | }
 60 | 
 61 | .Grid--1of3 > .Grid-cell {
 62 |   flex: 0 0 33.3333%;
 63 | }
 64 | 
 65 | .Grid--1of4 > .Grid-cell {
 66 |   flex: 0 0 25%;
 67 | }
 68 | 
 69 | @media (--break-sm) {
 70 |   .small-Grid--fit > .Grid-cell {
 71 |     flex: 1;
 72 |   }
 73 |   .small-Grid--full > .Grid-cell {
 74 |     flex: 0 0 100%;
 75 |   }
 76 |   .small-Grid--1of2 > .Grid-cell {
 77 |     flex: 0 0 50%;
 78 |   }
 79 |   .small-Grid--1of3 > .Grid-cell {
 80 |     flex: 0 0 33.3333%;
 81 |   }
 82 |   .small-Grid--1of4 > .Grid-cell {
 83 |     flex: 0 0 25%;
 84 |   }
 85 | }
 86 | 
 87 | @media (--break-md) {
 88 |   .med-Grid--fit > .Grid-cell {
 89 |     flex: 1;
 90 |   }
 91 |   .med-Grid--full > .Grid-cell {
 92 |     flex: 0 0 100%;
 93 |   }
 94 |   .med-Grid--1of2 > .Grid-cell {
 95 |     flex: 0 0 50%;
 96 |   }
 97 |   .med-Grid--1of3 > .Grid-cell {
 98 |     flex: 0 0 33.3333%;
 99 |   }
100 |   .med-Grid--1of4 > .Grid-cell {
101 |     flex: 0 0 25%;
102 |   }
103 | }
104 | 
105 | @media (--break-lg) {
106 |   .large-Grid--fit > .Grid-cell {
107 |     flex: 1;
108 |   }
109 |   .large-Grid--full > .Grid-cell {
110 |     flex: 0 0 100%;
111 |   }
112 |   .large-Grid--1of2 > .Grid-cell {
113 |     flex: 0 0 50%;
114 |   }
115 |   .large-Grid--1of3 > .Grid-cell {
116 |     flex: 0 0 33.3333%;
117 |   }
118 |   .large-Grid--1of4 > .Grid-cell {
119 |     flex: 0 0 25%;
120 |   }
121 | }
122 | 
123 | .Grid--gutters {
124 |   margin: -1em 0 1em -1em;
125 | }
126 | .Grid--gutters > .Grid-cell {
127 |   padding: 1em 0 0 1em;
128 | }
129 | 
130 | .Grid--guttersLg {
131 |   margin: -1.5em 0 1.5em -1.5em;
132 | }
133 | .Grid--guttersLg > .Grid-cell {
134 |   padding: 1.5em 0 0 1.5em;
135 | }
136 | 
137 | .Grid--guttersXl {
138 |   margin: -2em 0 2em -2em;
139 | }
140 | .Grid--guttersXl > .Grid-cell {
141 |   padding: 2em 0 0 2em;
142 | }
143 | 
144 | @media (--break-sm) {
145 |   .small-Grid--gutters {
146 |     margin: -1em 0 1em -1em;
147 |   }
148 |   .small-Grid--gutters > .Grid-cell {
149 |     padding: 1em 0 0 1em;
150 |   }
151 |   .small-Grid--guttersLg {
152 |     margin: -1.5em 0 1.5em -1.5em;
153 |   }
154 |   .small-Grid--guttersLg > .Grid-cell {
155 |     padding: 1.5em 0 0 1.5em;
156 |   }
157 |   .small-Grid--guttersXl {
158 |     margin: -2em 0 2em -2em;
159 |   }
160 |   .small-Grid--guttersXl > .Grid-cell {
161 |     padding: 2em 0 0 2em;
162 |   }
163 | }
164 | 
165 | @media (--break-md) {
166 |   .med-Grid--gutters {
167 |     margin: -1em 0 1em -1em;
168 |   }
169 |   .med-Grid--gutters > .Grid-cell {
170 |     padding: 1em 0 0 1em;
171 |   }
172 |   .med-Grid--guttersLg {
173 |     margin: -1.5em 0 1.5em -1.5em;
174 |   }
175 |   .med-Grid--guttersLg > .Grid-cell {
176 |     padding: 1.5em 0 0 1.5em;
177 |   }
178 |   .med-Grid--guttersXl {
179 |     margin: -2em 0 2em -2em;
180 |   }
181 |   .med-Grid--guttersXl > .Grid-cell {
182 |     padding: 2em 0 0 2em;
183 |   }
184 | }
185 | 
186 | @media (--break-lg) {
187 |   .large-Grid--gutters {
188 |     margin: -1em 0 1em -1em;
189 |   }
190 |   .large-Grid--gutters > .Grid-cell {
191 |     padding: 1em 0 0 1em;
192 |   }
193 |   .large-Grid--guttersLg {
194 |     margin: -1.5em 0 1.5em -1.5em;
195 |   }
196 |   .large-Grid--guttersLg > .Grid-cell {
197 |     padding: 1.5em 0 0 1.5em;
198 |   }
199 |   .large-Grid--guttersXl {
200 |     margin: -2em 0 2em -2em;
201 |   }
202 |   .large-Grid--guttersXl > .Grid-cell {
203 |     padding: 2em 0 0 2em;
204 |   }
205 | }
206 | 


--------------------------------------------------------------------------------
/assets/css/components/header.css:
--------------------------------------------------------------------------------
  1 | .Header {
  2 |   padding: 1.5em;
  3 |   background-color: rgba(147, 128, 108, 0.1);
  4 |   text-align: center;
  5 | }
  6 | @media (--break-lg) {
  7 |   .Header {
  8 |     padding: 3em 1.5em;
  9 |   }
 10 | }
 11 | 
 12 | .Header-title {
 13 |   margin: 0 0 0.15em;
 14 |   font-size: 1.8em;
 15 |   font-weight: 600;
 16 |   line-height: 1;
 17 |   word-spacing: 0.08em;
 18 | }
 19 | .Header-title i {
 20 |   font-family: serif;
 21 |   font-style: italic;
 22 |   font-weight: 400;
 23 | }
 24 | .Header-title a {
 25 |   border: 0;
 26 |   color: inherit;
 27 |   font-weight: inherit;
 28 | }
 29 | .Header-title a:focus, .Header-title a:hover, .Header-title a:active {
 30 |   text-decoration: none;
 31 | }
 32 | @media (--break-lg) {
 33 |   .Header-title {
 34 |     font-size: 4em;
 35 |   }
 36 | }
 37 | 
 38 | .Header-subTitle {
 39 |   margin: 0 0 1.5em;
 40 |   font-size: 0.8em;
 41 |   font-weight: 300;
 42 |   white-space: nowrap;
 43 | }
 44 | @media (--break-lg) {
 45 |   .Header-subTitle {
 46 |     margin: 1em 0 1.75em;
 47 |     font-size: 1.1em;
 48 |   }
 49 | }
 50 | 
 51 | .Header-actions {
 52 |   display: flex;
 53 |   align-items: stretch;
 54 |   flex-direction: column;
 55 |   font-size: 0.9em;
 56 | }
 57 | @media (--break-sm) {
 58 |   .Header-actions {
 59 |     align-items: center;
 60 |     flex-direction: row;
 61 |     justify-content: center;
 62 |   }
 63 | }
 64 | @media (--break-lg) {
 65 |   .Header-actions {
 66 |     font-size: 1.1em;
 67 |   }
 68 | }
 69 | 
 70 | .Header-button:first-child {
 71 |   margin: 0 0 1em;
 72 | }
 73 | @media (--break-sm) {
 74 |   .Header-button:first-child {
 75 |     margin: 0 1em 0 0;
 76 |   }
 77 | }
 78 | 
 79 | @media (--break-lg) {
 80 |   .Header--cozy {
 81 |     display: flex;
 82 |     padding: 1.5em;
 83 |     align-items: center;
 84 |   }
 85 |   .Header--cozy .Header-titles {
 86 |     display: flex;
 87 |     align-items: baseline;
 88 |   }
 89 |   .Header--cozy .Header-title {
 90 |     font-size: 1.5em;
 91 |   }
 92 |   .Header--cozy .Header-subTitle {
 93 |     margin: 0 0 0 1em;
 94 |     font-size: 0.8em;
 95 |     font-weight: 300;
 96 |     color: gray;
 97 |   }
 98 |   .Header--cozy .Header-actions {
 99 |     flex: 1;
100 |     justify-content: flex-end;
101 |     font-size: 0.9em;
102 |   }
103 | }
104 | 


--------------------------------------------------------------------------------
/assets/css/components/holy-grail.css:
--------------------------------------------------------------------------------
 1 | /**
 2 |  * 1. Avoid the IE 10-11 `min-height` bug.
 3 |  * 2. Set `flex-shrink` to `0` to prevent some browsers from
 4 |  *    letting these items shrink to smaller than their content's default
 5 |  *    minimum size. See http://bit.ly/1Mn35US for details.
 6 |  * 3. Use `%` instead of `vh` since `vh` is buggy in older mobile Safari.
 7 |  */
 8 | 
 9 | .HolyGrail {
10 |   display: flex;
11 |   height: 100%; /* 1, 3 */
12 |   flex-direction: column;
13 | }
14 | 
15 | .HolyGrail-header,
16 | .HolyGrail-footer {
17 |   flex: none; /* 2 */
18 | }
19 | 
20 | .HolyGrail-body {
21 |   display: flex;
22 |   flex: 1 0 auto; /* 2 */
23 |   flex-direction: column;
24 |   padding: var(--space);
25 | }
26 | 
27 | .HolyGrail-content {
28 |   margin-top: var(--space);
29 | }
30 | 
31 | .HolyGrail-nav {
32 |   order: -1;
33 | }
34 | 
35 | .HolyGrail-nav,
36 | .HolyGrail-ads {
37 |   padding: 1em;
38 |   border-radius: 3px;
39 |   background: rgba(147, 128, 108, 0.1);
40 | }
41 | 
42 | @media (--break-lg) {
43 |   .HolyGrail-body {
44 |     flex-direction: row;
45 |   }
46 |   .HolyGrail-content {
47 |     flex: 1;
48 |     padding: 0 var(--space-lg);
49 |     margin: 0;
50 |   }
51 |   .HolyGrail-nav, .HolyGrail-ads {
52 |     flex: 0 0 12em;
53 |   }
54 | }
55 | 


--------------------------------------------------------------------------------
/assets/css/components/image.css:
--------------------------------------------------------------------------------
 1 | .Image {
 2 |   display: block;
 3 |   width: 40px;
 4 |   height: auto;
 5 |   margin-top: 0.2em;
 6 | }
 7 | 
 8 | .Image--tiny {
 9 |   width: 30px;
10 | }
11 | 
12 | @media (--break-md) {
13 |   .Image {
14 |     width: 70px;
15 |   }
16 |   .Image--tiny {
17 |     width: 40px;
18 |   }
19 | }
20 | 


--------------------------------------------------------------------------------
/assets/css/components/input-add-on.css:
--------------------------------------------------------------------------------
 1 | .InputAddOn {
 2 |   display: flex;
 3 |   margin-bottom: 1.5em;
 4 | }
 5 | 
 6 | .InputAddOn-field {
 7 |   flex: 1;
 8 | }
 9 | .InputAddOn-field:not(:first-child) {
10 |   border-left: 0;
11 | }
12 | .InputAddOn-field:not(:last-child) {
13 |   border-right: 0;
14 | }
15 | 
16 | .InputAddOn-item {
17 |   background-color: rgba(147, 128, 108, 0.1);
18 |   color: #666666;
19 |   font: inherit;
20 |   font-weight: normal;
21 | }
22 | 
23 | .InputAddOn-field,
24 | .InputAddOn-item {
25 |   border: 1px solid rgba(147, 128, 108, 0.25);
26 |   padding: 0.5em 0.75em;
27 | }
28 | .InputAddOn-field:first-child,
29 | .InputAddOn-item:first-child {
30 |   border-radius: 2px 0 0 2px;
31 | }
32 | .InputAddOn-field:last-child,
33 | .InputAddOn-item:last-child {
34 |   border-radius: 0 2px 2px 0;
35 | }
36 | 


--------------------------------------------------------------------------------
/assets/css/components/media.css:
--------------------------------------------------------------------------------
 1 | .Media {
 2 |   display: flex;
 3 |   align-items: flex-start;
 4 |   margin-bottom: 1em;
 5 | }
 6 | 
 7 | .Media-figure {
 8 |   margin-right: 1em;
 9 | }
10 | 
11 | .Media-body {
12 |   flex: 1;
13 | }
14 | .Media-body,
15 | .Media-body :last-child {
16 |   margin-bottom: 0;
17 | }
18 | 
19 | .Media-title {
20 |   margin: 0 0 .5em;
21 | }
22 | 
23 | .Media--center {
24 |   align-items: center;
25 | }
26 | 
27 | .Media--reverse > .Media-figure {
28 |   order: 1;
29 |   margin: 0 0 0 1em;
30 | }
31 | 


--------------------------------------------------------------------------------
/assets/css/components/notice.css:
--------------------------------------------------------------------------------
1 | .Notice {
2 |   background-color: hsl(90, 100%, 93%);
3 |   color: hsla(0, 0%, 0%, .6);
4 |   font-size: .9em;
5 |   margin-bottom: var(--space);
6 |   padding: 1.2em 1.5em;
7 | }
8 | 


--------------------------------------------------------------------------------
/assets/css/components/section.css:
--------------------------------------------------------------------------------
 1 | .Section {
 2 |   padding: 0 var(--space);
 3 | }
 4 | .Section:nth-child(2n) {
 5 |   background-color: hsla(31, 15%, 50%, 0.1);
 6 |   overflow: hidden; /* Contain margins. */
 7 | }
 8 | .Section::before,
 9 | .Section::after {
10 |   content: '\00a0'; /*   */
11 |   display: block;
12 |   height: 0px;
13 |   visibility: hidden;
14 | }
15 | .Section::before {
16 |   margin-bottom: var(--space);
17 | }
18 | .Section::after {
19 |   margin-top: var(--space);
20 | }
21 | @media (--break-lg) {
22 |   .Section {
23 |     padding: 0 var(--space-lg);
24 |   }
25 |   .Section::before {
26 |     margin-bottom: var(--space-lg);
27 |   }
28 |   .Section::after {
29 |     margin-top: var(--space-lg);
30 |   }
31 | }
32 | 
33 | .Section-heading {
34 |   text-align: center;
35 | }
36 | 
37 | @media (--break-lg) {
38 |   .Section-list {
39 |     padding: 0;
40 |     margin: 0 calc(2 * var(--space-lg)) var(--space-lg);
41 |   }
42 | }
43 | 


--------------------------------------------------------------------------------
/assets/css/components/site.css:
--------------------------------------------------------------------------------
 1 | /**
 2 |  * 1. Avoid the IE 10-11 `min-height` bug.
 3 |  * 2. Set `flex-shrink` to `0` to prevent some browsers from
 4 |  *    letting these items shrink to smaller than their content's default
 5 |  *    minimum size. See http://bit.ly/1Mn35US for details.
 6 |  * 3. Use `%` instead of `vh` since `vh` is buggy in older mobile Safari.
 7 |  */
 8 | 
 9 | .Site {
10 |   display: flex;
11 |   flex-direction: column;
12 |   height: 100%; /* 1, 3 */
13 | }
14 | 
15 | .Site-header,
16 | .Site-footer {
17 |   flex: none; /* 2 */
18 | }
19 | 
20 | .Site-content {
21 |   flex: 1 0 auto; /* 2 */
22 |   padding: var(--space) var(--space) 0;
23 |   width: 100%;
24 | }
25 | .Site-content::after {
26 |   content: '\00a0'; /*   */
27 |   display: block;
28 |   margin-top: var(--space);
29 |   height: 0px;
30 |   visibility: hidden;
31 | }
32 | @media (--break-lg) {
33 |   .Site-content {
34 |     padding-top: var(--space-lg);
35 |   }
36 |   .Site-content::after {
37 |     margin-top: var(--space-lg);
38 |   }
39 | }
40 | 
41 | .Site-content--full {
42 |   padding: 0;
43 | }
44 | .Site-content--full::after {
45 |   content: none;
46 | }
47 | 


--------------------------------------------------------------------------------
/assets/css/main.css:
--------------------------------------------------------------------------------
 1 | @import 'normalize.css';
 2 | @import 'suitcss-utils-display';
 3 | @import 'suitcss-utils-text';
 4 | 
 5 | @import './base/variables';
 6 | @import './base/custom-media';
 7 | @import './base/elements';
 8 | 
 9 | @import './components/aligner';
10 | @import './components/browser';
11 | @import './components/button';
12 | @import './components/container';
13 | @import './components/demo';
14 | @import './components/error';
15 | @import './components/feature';
16 | @import './components/footer';
17 | @import './components/grid';
18 | @import './components/header';
19 | @import './components/holy-grail';
20 | @import './components/image';
21 | @import './components/input-add-on';
22 | @import './components/media';
23 | @import './components/notice';
24 | @import './components/section';
25 | @import './components/site';
26 | 
27 | @import './utils/compat';
28 | @import './utils/media';
29 | @import './utils/size';
30 | 
31 | @import './vendor/font-awesome-extensions';
32 | @import './vendor/highlight';
33 | @import './vendor/twitter';
34 | 


--------------------------------------------------------------------------------
/assets/css/utils/compat.css:
--------------------------------------------------------------------------------
 1 | /**
 2 |  * Fixes the min-height bug in IE10-11.
 3 |  * This class should be added to a container element as described in
 4 |  * Flexbug #3. See http://bit.ly/1gy8OJS for details.
 5 |  */
 6 | .u-ieMinHeightBugFix {
 7 |   display: flex;
 8 |   flex-direction: column;
 9 | }
10 | 


--------------------------------------------------------------------------------
/assets/css/utils/media.css:
--------------------------------------------------------------------------------
  1 | @import '../base/custom-media';
  2 | 
  3 | .u-full {
  4 |   width: 100% !important;
  5 |   flex: none !important;
  6 | }
  7 | 
  8 | .u-1of2 {
  9 |   width: 50% !important;
 10 |   flex: none !important;
 11 | }
 12 | 
 13 | .u-1of3 {
 14 |   width: 33.3333% !important;
 15 |   flex: none !important;
 16 | }
 17 | 
 18 | .u-2of3 {
 19 |   width: 66.6667% !important;
 20 |   flex: none !important;
 21 | }
 22 | 
 23 | .u-1of4 {
 24 |   width: 25% !important;
 25 |   flex: none !important;
 26 | }
 27 | 
 28 | .u-3of4 {
 29 |   width: 75% !important;
 30 |   flex: none !important;
 31 | }
 32 | 
 33 | @media (--break-sm) {
 34 |   .u-small-full {
 35 |     width: 100% !important;
 36 |     flex: none !important;
 37 |   }
 38 |   .u-small-1of2 {
 39 |     width: 50% !important;
 40 |     flex: none !important;
 41 |   }
 42 |   .u-small-1of3 {
 43 |     width: 33.3333% !important;
 44 |     flex: none !important;
 45 |   }
 46 |   .u-small-2of3 {
 47 |     width: 66.6667% !important;
 48 |     flex: none !important;
 49 |   }
 50 |   .u-small-1of4 {
 51 |     width: 25% !important;
 52 |     flex: none !important;
 53 |   }
 54 |   .u-small-3of4 {
 55 |     width: 75% !important;
 56 |     flex: none !important;
 57 |   }
 58 | }
 59 | 
 60 | @media (--break-md) {
 61 |   .u-med-full {
 62 |     width: 100% !important;
 63 |     flex: none !important;
 64 |   }
 65 |   .u-med-1of2 {
 66 |     width: 50% !important;
 67 |     flex: none !important;
 68 |   }
 69 |   .u-med-1of3 {
 70 |     width: 33.3333% !important;
 71 |     flex: none !important;
 72 |   }
 73 |   .u-med-2of3 {
 74 |     width: 66.6667% !important;
 75 |     flex: none !important;
 76 |   }
 77 |   .u-med-1of4 {
 78 |     width: 25% !important;
 79 |     flex: none !important;
 80 |   }
 81 |   .u-med-3of4 {
 82 |     width: 75% !important;
 83 |     flex: none !important;
 84 |   }
 85 | }
 86 | 
 87 | @media (--break-lg) {
 88 |   .u-large-full {
 89 |     width: 100% !important;
 90 |     flex: none !important;
 91 |   }
 92 |   .u-large-1of2 {
 93 |     width: 50% !important;
 94 |     flex: none !important;
 95 |   }
 96 |   .u-large-1of3 {
 97 |     width: 33.3333% !important;
 98 |     flex: none !important;
 99 |   }
100 |   .u-large-2of3 {
101 |     width: 66.6667% !important;
102 |     flex: none !important;
103 |   }
104 |   .u-large-1of4 {
105 |     width: 25% !important;
106 |     flex: none !important;
107 |   }
108 |   .u-large-3of4 {
109 |     width: 75% !important;
110 |     flex: none !important;
111 |   }
112 | }
113 | 


--------------------------------------------------------------------------------
/assets/css/utils/size.css:
--------------------------------------------------------------------------------
1 | .u-smaller {
2 |   font-size: 0.85em;
3 | }
4 | 
5 | .u-bigger {
6 |   font-size: 1.2em;
7 | }
8 | 


--------------------------------------------------------------------------------
/assets/css/vendor/font-awesome-extensions.css:
--------------------------------------------------------------------------------
1 | .icon-big {
2 |   font-size: 1.5em;
3 | }
4 | 


--------------------------------------------------------------------------------
/assets/css/vendor/highlight.css:
--------------------------------------------------------------------------------
 1 | @import "highlight.js/styles/github";
 2 | 
 3 | pre {
 4 |   border-radius: 3px;
 5 |   background: hsla(31, 15%, 50%, 0.1);
 6 |   font-size: 0.85em;
 7 |   margin-bottom: calc(var(--space)/0.85);
 8 |   overflow-x: auto;
 9 |   padding: 1.25em 1.5em;
10 | }
11 | 


--------------------------------------------------------------------------------
/assets/css/vendor/twitter.css:
--------------------------------------------------------------------------------
1 | .twitter-follow-button {
2 |   width: 235px !important;
3 | }
4 | 
5 | .twitter-color {
6 |   color: #00ACED;
7 | }
8 | 


--------------------------------------------------------------------------------
/assets/images/browser-logos.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/philipwalton/solved-by-flexbox/01af9bc0c2c80ce67955667e8413fe5996f140b3/assets/images/browser-logos.jpg


--------------------------------------------------------------------------------
/assets/images/grids.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/philipwalton/solved-by-flexbox/01af9bc0c2c80ce67955667e8413fe5996f140b3/assets/images/grids.jpg


--------------------------------------------------------------------------------
/assets/images/holy-grail.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/philipwalton/solved-by-flexbox/01af9bc0c2c80ce67955667e8413fe5996f140b3/assets/images/holy-grail.jpg


--------------------------------------------------------------------------------
/assets/images/input-add-ons.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/philipwalton/solved-by-flexbox/01af9bc0c2c80ce67955667e8413fe5996f140b3/assets/images/input-add-ons.jpg


--------------------------------------------------------------------------------
/assets/images/kitten.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/philipwalton/solved-by-flexbox/01af9bc0c2c80ce67955667e8413fe5996f140b3/assets/images/kitten.jpg


--------------------------------------------------------------------------------
/assets/images/media-object.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/philipwalton/solved-by-flexbox/01af9bc0c2c80ce67955667e8413fe5996f140b3/assets/images/media-object.jpg


--------------------------------------------------------------------------------
/assets/images/sticky-footer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/philipwalton/solved-by-flexbox/01af9bc0c2c80ce67955667e8413fe5996f140b3/assets/images/sticky-footer.jpg


--------------------------------------------------------------------------------
/assets/images/vertical-centering.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/philipwalton/solved-by-flexbox/01af9bc0c2c80ce67955667e8413fe5996f140b3/assets/images/vertical-centering.jpg


--------------------------------------------------------------------------------
/assets/main.js:
--------------------------------------------------------------------------------
 1 | import {getCLS, getFCP, getFID, getLCP} from 'web-vitals';
 2 | 
 3 | const thresholds = {
 4 |   CLS: [0.1, 0.25],
 5 |   FCP: [1800, 3000],
 6 |   FID: [100, 300],
 7 |   LCP: [2500, 4000],
 8 | }
 9 | 
10 | function getRating(value, thresholds) {
11 |   if (value > thresholds[1]) {
12 |     return 'poor';
13 |   }
14 |   if (value > thresholds[0]) {
15 |     return 'ni';
16 |   }
17 |   return 'good';
18 | }
19 | 
20 | function sendToGoogleAnalytics({name, value, delta, id}) {
21 |   gtag('event', name, {
22 |     value: Math.round(name === 'CLS' ? delta * 1000 : delta),
23 |     event_category: 'Web Vitals',
24 |     event_label: getRating(value, thresholds[name]),
25 |     event_id: id,
26 |     non_interaction: true,
27 |   });
28 | }
29 | 
30 | getCLS(sendToGoogleAnalytics);
31 | getFCP(sendToGoogleAnalytics);
32 | getFID(sendToGoogleAnalytics);
33 | getLCP(sendToGoogleAnalytics);
34 | 


--------------------------------------------------------------------------------
/config.json:
--------------------------------------------------------------------------------
1 | {
2 |   "title": "Solved by Flexbox",
3 |   "tagline": "Cleaner, hack-free CSS",
4 |   "description": "A showcase of problems once hard or impossible to solve with CSS alone, now made trivially easy with Flexbox."
5 | }
6 | 


--------------------------------------------------------------------------------
/demos/grids.md:
--------------------------------------------------------------------------------
  1 | ---
  2 | template: default.html
  3 | title: Better, Simpler Grid Systems
  4 | excerpt: Flexbox gives us most of the features we want from a grid system out of the box. And sizing and alignment are just one or two properties away.
  5 | ---
  6 | 
  7 | Most grid systems today use one of two layout methods: `float` or `inline-block`. But neither of these methods were really intended to be used for layout and as a result have pretty significant problems and limitations.
  8 | 
  9 | Using floats requires clearing them which has a whole host of layout issues, most notoriously that clearing an element sometimes forces it below an unrelated part of the page (take this [Bootstrap issue](https://github.com/twbs/bootstrap/issues/295#issuecomment-2282969) for example). In addition, clearing floats usually requires using both before and after pseudo-elements, preventing you from using them for something else.
 10 | 
 11 | Inline block layouts must address the problem of [white-space between inline-block items](http://css-tricks.com/fighting-the-space-between-inline-block-elements/), and all of the [solutions](http://davidwalsh.name/remove-whitespace-inline-block) to that problem are [hacky](https://github.com/suitcss/components-grid/blob/master/lib/grid.css#L30) and [annoying](https://twitter.com/thierrykoblentz/status/305152267374428160).
 12 | 
 13 | Flexbox not only eliminates these problems, it opens up an entirely new world of possibilities.
 14 | 
 15 | ## Features of a Flexbox Grid System
 16 | 
 17 | Grid systems usually come with a myriad of sizing options, but the vast majority of the time you just want two or three elements side-by-side. Given this, why should we be required to put sizing classes on every single cell?
 18 | 
 19 | Listed below are some of my criteria for an ideal grid system. Fortunately, with Flexbox we get most of these features for free.
 20 | 
 21 | - By default, each grid cell is the same width and height as every other cell in the row. Basically they all size to fit by default.
 22 | - For finer control, you can add sizing classes to individual cells. Without these classes, the cells simply divide up the available space as usual.
 23 | - For responsive grids, you can add media query-specific classes to the cells.
 24 | - Individual cells can be aligned vertically to the top, bottom, or middle.
 25 | - When you want all of the cells in a grid to have the same sizing, media, or alignment values, you should be able to just add a single class to the container to avoid unnecessary repetition.
 26 | - Grids can be nested as many levels deep as needed.
 27 | 
 28 | ### Basic Grids
 29 | 
 30 | The grid cells below do not specify any widths, they just naturally space themselves equally and expand to fit the entire row. They're also equal height by default.
 31 | 
 32 | <div class="Grid Grid--gutters u-textCenter">
 33 |   <div class="Grid-cell">
 34 |     <div class="Demo">1/2</div>
 35 |   </div>
 36 |   <div class="Grid-cell">
 37 |     <div class="Demo">1/2</div>
 38 |   </div>
 39 | </div>
 40 | 
 41 | <div class="Grid Grid--gutters u-textCenter">
 42 |   <div class="Grid-cell">
 43 |     <div class="Demo">1/3</div>
 44 |   </div>
 45 |   <div class="Grid-cell">
 46 |     <div class="Demo">1/3</div>
 47 |   </div>
 48 |   <div class="Grid-cell">
 49 |     <div class="Demo">1/3</div>
 50 |   </div>
 51 | </div>
 52 | 
 53 | <div class="Grid Grid--gutters u-textCenter">
 54 |   <div class="Grid-cell">
 55 |     <div class="Demo">1/4</div>
 56 |   </div>
 57 |   <div class="Grid-cell">
 58 |     <div class="Demo">1/4</div>
 59 |   </div>
 60 |   <div class="Grid-cell">
 61 |     <div class="Demo">1/4</div>
 62 |   </div>
 63 |   <div class="Grid-cell">
 64 |     <div class="Demo">1/4</div>
 65 |   </div>
 66 | </div>
 67 | 
 68 | <div class="Grid Grid--gutters Grid--flexCells">
 69 |   <div class="Grid-cell">
 70 |     <div class="Demo">
 71 |       Full-height, even when my content doesn't fill the space.
 72 |     </div>
 73 |   </div>
 74 | 
 75 |   <div class="Grid-cell">
 76 |     <div class="Demo">
 77 |       Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mollis velit non gravida venenatis. Praesent consequat lectus purus, ut scelerisque velit condimentum eu. Maecenas sagittis ante ut turpis varius interdum. Quisque tellus ipsum, eleifend non ipsum id, suscipit ultricies neque.
 78 |     </div>
 79 |   </div>
 80 | </div>
 81 | 
 82 | ### Individual Sizing
 83 | 
 84 | When equal widths aren't what you want, you can add sizing classes to individual cells. Cells without sizing classes simply divide up the remaining space as normal.
 85 | 
 86 | The cells below labeled "auto" do not have sizing classes specified.
 87 | 
 88 | <div class="Grid Grid--gutters u-textCenter">
 89 |   <div class="Grid-cell u-1of2">
 90 |     <div class="Demo">1/2</div>
 91 |   </div>
 92 |   <div class="Grid-cell">
 93 |     <div class="Demo">auto</div>
 94 |   </div>
 95 |   <div class="Grid-cell">
 96 |     <div class="Demo">auto</div>
 97 |   </div>
 98 | </div>
 99 | 
100 | <div class="Grid Grid--gutters u-textCenter">
101 |   <div class="Grid-cell">
102 |     <div class="Demo">auto</div>
103 |   </div>
104 |   <div class="Grid-cell u-1of3">
105 |     <div class="Demo">1/3</div>
106 |   </div>
107 | </div>
108 | 
109 | <div class="Grid Grid--gutters u-textCenter">
110 |   <div class="Grid-cell u-1of4">
111 |     <div class="Demo">1/4</div>
112 |   </div>
113 |   <div class="Grid-cell">
114 |     <div class="Demo">auto</div>
115 |   </div>
116 |   <div class="Grid-cell u-1of3">
117 |     <div class="Demo">1/3</div>
118 |   </div>
119 | </div>
120 | 
121 | ### Responsive
122 | 
123 | Responsive Grids work by adding media classes to the Grid cells or containers. When those media values are met, the grids automatically adjust accordingly.
124 | 
125 | The cells below should be full width by default and scaled to fit above `48em`. Resize your browser to see them in action.
126 | 
127 | <div class="Grid Grid--gutters Grid--full large-Grid--fit u-textCenter">
128 |   <div class="Grid-cell">
129 |     <div class="Demo">Full / Halves</div>
130 |   </div>
131 |   <div class="Grid-cell">
132 |     <div class="Demo">Full / Halves</div>
133 |   </div>
134 | </div>
135 | <div class="Grid Grid--gutters Grid--full large-Grid--fit u-textCenter">
136 |   <div class="Grid-cell">
137 |     <div class="Demo">Full / Thirds</div>
138 |   </div>
139 |   <div class="Grid-cell">
140 |     <div class="Demo">Full / Thirds</div>
141 |   </div>
142 |   <div class="Grid-cell">
143 |     <div class="Demo">Full / Thirds</div>
144 |   </div>
145 | </div>
146 | 
147 | ### Grid-ception
148 | 
149 | Grid components are infinitely nestable inside of other grid components.
150 | 
151 | <div class="Grid Grid--gutters Grid--flexCells u-textCenter">
152 |   <div class="Grid-cell">
153 |     <div class="Demo">
154 |       <div class="Grid Grid--gutters u-textCenter">
155 |         <div class="Grid-cell u-1of3">
156 |           <div class="Demo">1/3</div>
157 |         </div>
158 |         <div class="Grid-cell">
159 |           <div class="Demo">
160 |             <div class="Grid Grid--gutters u-textCenter">
161 |               <div class="Grid-cell">
162 |                 <div class="Demo">1/2</div>
163 |               </div>
164 |               <div class="Grid-cell">
165 |                 <div class="Demo">1/2</div>
166 |               </div>
167 |             </div>
168 |           </div>
169 |         </div>
170 |       </div>
171 |     </div>
172 |   </div>
173 |   <div class="Grid-cell u-1of3">
174 |     <div class="Demo">1/3</div>
175 |   </div>
176 | </div>
177 | 
178 | ## Alignment Features
179 | 
180 | ### Top-aligned Grid Cells
181 | 
182 | <div class="Grid Grid--gutters Grid--top">
183 |   <div class="Grid-cell">
184 |     <div class="Demo">
185 |       This cell should be top-aligned.
186 |     </div>
187 |   </div>
188 |   <div class="Grid-cell u-1of2">
189 |     <div class="Demo">
190 |       Pellentesque sagittis vel erat ac laoreet. Phasellus ac aliquet enim, eu aliquet sem. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed pulvinar porta leo, eu ultricies nunc sollicitudin vitae. Curabitur pulvinar dolor lectus, quis porta turpis ullamcorper nec. Quisque eget varius turpis, quis iaculis nibh.
191 |     </div>
192 |   </div>
193 |   <div class="Grid-cell">
194 |     <div class="Demo">
195 |       This cell should be top-aligned.
196 |     </div>
197 |   </div>
198 | </div>
199 | 
200 | ### Bottom-aligned Grid Cells
201 | 
202 | <div class="Grid Grid--gutters Grid--bottom">
203 |   <div class="Grid-cell">
204 |     <div class="Demo">
205 |       This cell should be bottom-aligned.
206 |     </div>
207 |   </div>
208 |   <div class="Grid-cell">
209 |     <div class="Demo">
210 |       Curabitur pulvinar dolor lectus, quis porta turpis ullamcorper nec. Quisque eget varius turpis, quis iaculis nibh. Ut interdum ligula id metus hendrerit cursus. Integer eu leo felis. Aenean commodo ultrices nunc, sit amet blandit elit gravida in.
211 |     </div>
212 |   </div>
213 |   <div class="Grid-cell">
214 |     <div class="Demo">
215 |       This cell should be bottom-aligned.
216 |     </div>
217 |   </div>
218 | </div>
219 | 
220 | ### Vertically Centered Grid Cells
221 | 
222 | <div class="Grid Grid--gutters Grid--center">
223 |   <div class="Grid-cell">
224 |     <div class="Demo">
225 |       This cell should be vertically-centered with the cell to its right.
226 |     </div>
227 |   </div>
228 |   <div class="Grid-cell">
229 |     <div class="Demo">
230 |       Curabitur pulvinar dolor lectus, quis porta turpis ullamcorper nec. Quisque eget varius turpis, quis iaculis nibh. Ut interdum ligula id metus hendrerit cursus. Integer eu leo felis. Aenean commodo ultrices nunc, sit amet blandit elit gravida in. Sed est ligula, ornare ac nisi adipiscing, iaculis facilisis tellus. Nullam vel facilisis libero. Duis semper lobortis elit, vitae dictum erat.</div>
231 |   </div>
232 | </div>
233 | 
234 | ### Mixed Vertical Alignment
235 | 
236 | <div class="Grid Grid--gutters">
237 |   <div class="Grid-cell Grid-cell--top">
238 |     <div class="Demo">
239 |       This cell should be top aligned.
240 |     </div>
241 |   </div>
242 |   <div class="Grid-cell">
243 |     <div class="Demo">
244 |       Curabitur pulvinar dolor lectus, quis porta turpis ullamcorper nec. Quisque eget varius turpis, quis iaculis nibh. Ut interdum ligula id metus hendrerit cursus. Integer eu leo felis. Aenean commodo ultrices nunc, sit amet blandit elit gravida in. Sed est ligula, ornare ac nisi adipiscing, iaculis facilisis tellus.</div>
245 |   </div>
246 |   <div class="Grid-cell Grid-cell--center">
247 |     <div class="Demo">
248 |       This cell should be center-aligned.
249 |     </div>
250 |   </div>
251 |   <div class="Grid-cell Grid-cell--bottom">
252 |     <div class="Demo">
253 |       This cell should be bottom-aligned.
254 |     </div>
255 |   </div>
256 | </div>
257 | 
258 | ## The HTML
259 | 
260 | ```html
261 | <div class="Grid">
262 |   <div class="Grid-cell">…</div>
263 |   <div class="Grid-cell">…</div>
264 |   <div class="Grid-cell">…</div>
265 | </div>
266 | ```
267 | 
268 | ## The CSS
269 | 
270 | ### Basic Grid Styles
271 | 
272 | ```css
273 | .Grid {
274 |   display: flex;
275 | }
276 | 
277 | .Grid-cell {
278 |   flex: 1;
279 | }
280 | ```
281 | 
282 | ### Grid Style Modifiers
283 | 
284 | ```css
285 | /* With gutters */
286 | .Grid--gutters {
287 |   margin: -1em 0 0 -1em;
288 | }
289 | .Grid--gutters > .Grid-cell {
290 |   padding: 1em 0 0 1em;
291 | }
292 | 
293 | /* Alignment per row */
294 | .Grid--top {
295 |   align-items: flex-start;
296 | }
297 | .Grid--bottom {
298 |   align-items: flex-end;
299 | }
300 | .Grid--center {
301 |   align-items: center;
302 | }
303 | 
304 | /* Alignment per cell */
305 | .Grid-cell--top {
306 |   align-self: flex-start;
307 | }
308 | .Grid-cell--bottom {
309 |   align-self: flex-end;
310 | }
311 | .Grid-cell--center {
312 |   align-self: center;
313 | }
314 | ```
315 | 
316 | ### Responsive Modifiers (a mobile-first approach)
317 | 
318 | ```css
319 | /* Base classes for all media */
320 | .Grid--fit > .Grid-cell {
321 |   flex: 1;
322 | }
323 | .Grid--full > .Grid-cell {
324 |   flex: 0 0 100%;
325 | }
326 | .Grid--1of2 > .Grid-cell {
327 |   flex: 0 0 50%
328 | }
329 | .Grid--1of3 > .Grid-cell {
330 |   flex: 0 0 33.3333%
331 | }
332 | .Grid--1of4 > .Grid-cell {
333 |   flex: 0 0 25%
334 | }
335 | 
336 | /* Small to medium screens */
337 | @media (min-width: 24em) {
338 |   .small-Grid--fit > .Grid-cell {
339 |     flex: 1;
340 |   }
341 |   .small-Grid--full > .Grid-cell {
342 |     flex: 0 0 100%;
343 |   }
344 |   .small-Grid--1of2 > .Grid-cell {
345 |     flex: 0 0 50%
346 |   }
347 |   .small-Grid--1of3 > .Grid-cell {
348 |     flex: 0 0 33.3333%
349 |   }
350 |   .small-Grid--1of4 > .Grid-cell {
351 |     flex: 0 0 25%
352 |   }
353 | }
354 | 
355 | /* Large screens */
356 | @media (min-width: 48em) {
357 |   .large-Grid--fit > .Grid-cell {
358 |     flex: 1;
359 |   }
360 |   .large-Grid--full > .Grid-cell {
361 |     flex: 0 0 100%;
362 |   }
363 |   .large-Grid--1of2 > .Grid-cell {
364 |     flex: 0 0 50%
365 |   }
366 |   .large-Grid--1of3 > .Grid-cell {
367 |     flex: 0 0 33.3333%
368 |   }
369 |   .large-Grid--1of4 > .Grid-cell {
370 |     flex: 0 0 25%
371 |   }
372 | }
373 | ```
374 | 
375 | View the full [source](https://github.com/philipwalton/solved-by-flexbox/blob/master/assets/css/components/grid.css) for the `Grid` component used in this demo on Github.
376 | 


--------------------------------------------------------------------------------
/demos/holy-grail.md:
--------------------------------------------------------------------------------
  1 | ---
  2 | template: holy-grail.html
  3 | title: Holy Grail Layout
  4 | excerpt: This classic problem has been challenging CSS hackers for years, yet none of the historical solutions have fully solved it. With Flexbox, it's finally possible.
  5 | ---
  6 | 
  7 | The [Holy Grail Layout](http://en.wikipedia.org/wiki/Holy_Grail_(web_design)) is a classic CSS problem with various solutions presented over time. If you're unfamiliar with the history of the Holy Grail layout, this [A List Apart article](http://alistapart.com/article/holygrail) offers a pretty good summary and links to a few of the more well-known solutions.
  8 | 
  9 | At its core, the Holy Grail Layout is a page with a header, footer, and three columns. The center column contains the main content, and the left and right columns contain supplemental content like ads or navigation.
 10 | 
 11 | Most CSS solutions to this problem aim to meet a few goals:
 12 | 
 13 | - They should have a fluid center with fixed-width sidebars.
 14 | - The center column (main content) should appear first in the HTML source.
 15 | - All columns should be the same height, regardless of which column is actually the tallest.
 16 | - They should require minimal markup.
 17 | - The footer should "stick" to the bottom of the page when content is sparse.
 18 | 
 19 | Unfortunately, because of the nature of these goals and the original limitations of CSS, none of the classic solutions to this problem were ever able to satisfy all of them.
 20 | 
 21 | With Flexbox, a complete solution is finally possible.
 22 | 
 23 | ## The HTML
 24 | 
 25 | ```html
 26 | <body class="HolyGrail">
 27 |   <header>…</header>
 28 |   <div class="HolyGrail-body">
 29 |     <main class="HolyGrail-content">…</main>
 30 |     <nav class="HolyGrail-nav">…</nav>
 31 |     <aside class="HolyGrail-ads">…</aside>
 32 |   </div>
 33 |   <footer>…</footer>
 34 | </body>
 35 | ```
 36 | 
 37 | ## The CSS
 38 | 
 39 | Getting the center content row to stretch and the footer to stick to the bottom is solved with the same technique shown in the [Sticky Footer](../sticky-footer/) example. The only difference is the center row of the Holy Grail layout (`.HolyGrail-body`) needs to be `display:flex` in order to properly arrange its children.
 40 | 
 41 | ```css
 42 | .HolyGrail {
 43 |   display: flex;
 44 |   min-height: 100vh;
 45 |   flex-direction: column;
 46 | }
 47 | 
 48 | .HolyGrail-body {
 49 |   display: flex;
 50 |   flex: 1;
 51 | }
 52 | ```
 53 | 
 54 | Styling three equal-height columns with a fluid center and fixed-width sidebars is just as easy:
 55 | 
 56 | ```css
 57 | .HolyGrail-content {
 58 |   flex: 1;
 59 | }
 60 | 
 61 | .HolyGrail-nav, .HolyGrail-ads {
 62 |   /* 12em is the width of the columns */
 63 |   flex: 0 0 12em;
 64 | }
 65 | 
 66 | .HolyGrail-nav {
 67 |   /* put the nav on the left */
 68 |   order: -1;
 69 | }
 70 | ```
 71 | 
 72 | <aside class="Notice"><strong>Note:</strong>&nbsp; the CSS required to make this demo work cross-browser is slightly different from the CSS shown in the examples above, which assume a fully spec-compliant browser. See the <a href="https://github.com/philipwalton/solved-by-flexbox/blob/master/assets/css/components/holy-grail.css">comments in the source</a> for more details.</aside>
 73 | 
 74 | 
 75 | ### Being Responsive
 76 | 
 77 | The Holy Grail layout came from an era of Web design when pretty much everyone was browsing on a computer. But with the increasing number of mobile devices and the rising popularity of responsive design, the Holy Grail layout has gone mostly out of fashion.
 78 | 
 79 | Either way, with Flexbox, creating a mobile-first and mobile-friendly version of the Holy Grail layout is easy. The gist is to simply make the center section `flex-direction:column` by default and then `flex-direction:row` for larger screens.
 80 | 
 81 | Here's a complete example that is responsive and mobile-first. You can also resize this browser window to see it in action.
 82 | 
 83 | ```css
 84 | .HolyGrail,
 85 | .HolyGrail-body {
 86 |   display: flex;
 87 |   flex-direction: column;
 88 | }
 89 | 
 90 | .HolyGrail-nav {
 91 |   order: -1;
 92 | }
 93 | 
 94 | @media (min-width: 768px) {
 95 |   .HolyGrail-body {
 96 |     flex-direction: row;
 97 |     flex: 1;
 98 |   }
 99 |   .HolyGrail-content {
100 |     flex: 1;
101 |   }
102 |   .HolyGrail-nav, .HolyGrail-ads {
103 |     /* 12em is the width of the columns */
104 |     flex: 0 0 12em;
105 |   }
106 | }
107 | ```
108 | 
109 | View the full [source](https://github.com/philipwalton/solved-by-flexbox/blob/master/assets/css/components/holy-grail.css) for the `HolyGrail` component used in this demo on Github.
110 | 


--------------------------------------------------------------------------------
/demos/input-add-ons.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | template: default.html
 3 | title: Input Add-ons
 4 | excerpt: Creating full-width, fluid input/button pairs has been impossible for most of the history of CSS. With Flexbox it couldn't be easier.
 5 | ---
 6 | 
 7 | Because of the way input sizing works in CSS, it's almost impossible to append or prepend another element to it and have the input field behave fluidly and take up the remaining space.
 8 | 
 9 | The only existing way to do this is to either know the exact width of the input, or to use something like `display:table-cell`, which has its own set of problems, most notably the difficulty with positioning anything absolutely inside of the add-on in certain browsers.
10 | 
11 | With Flexbox, all these problems go away, and the code is trivially simple. In addition, you get the input field and the input add-on to be the same height for free.
12 | 
13 | <div class="Grid Grid--guttersLg Grid--full med-Grid--fit">
14 |   <div class="Grid-cell">
15 |     <h2>Add-on Prepended</h2>
16 |     <div class="InputAddOn">
17 |       <span class="InputAddOn-item">Amount</span>
18 |       <input class="InputAddOn-field">
19 |     </div>
20 |     <div class="InputAddOn">
21 |       <button class="InputAddOn-item"><span class="icon icon-search"></span></button>
22 |       <input class="InputAddOn-field">
23 |     </div>
24 |   </div>
25 |   <div class="Grid-cell">
26 |     <h2>Add-on Appended</h2>
27 |     <div class="InputAddOn">
28 |       <input class="InputAddOn-field">
29 |       <button class="InputAddOn-item">Go</button>
30 |     </div>
31 |     <div class="InputAddOn">
32 |       <input class="InputAddOn-field">
33 |       <button class="InputAddOn-item"><span class="icon icon-star"></span></button>
34 |     </div>
35 |   </div>
36 | </div>
37 | 
38 | ## Appended and Prepended Add-ons
39 | 
40 | <div class="Grid Grid--guttersLg Grid--full med-Grid--fit">
41 |   <div class="Grid-cell">
42 |     <div class="InputAddOn">
43 |       <span class="InputAddOn-item"><span class="icon icon-envelope"></span></span>
44 |       <input class="InputAddOn-field" placeholder="Example One">
45 |       <button class="InputAddOn-item">Send</button>
46 |     </div>
47 |   </div>
48 |   <div class="Grid-cell">
49 |     <div class="InputAddOn">
50 |       <span class="InputAddOn-item"><span class="icon icon-lock"></span></span>
51 |       <input class="InputAddOn-field" placeholder="Example One">
52 |       <button class="InputAddOn-item">Encrypt</button>
53 |     </div>
54 |   </div>
55 | </div>
56 | 
57 | ## The HTML
58 | 
59 | ```html
60 | <!-- appending -->
61 | <div class="InputAddOn">
62 |   <input class="InputAddOn-field">
63 |   <button class="InputAddOn-item">…</button>
64 | </div>
65 | 
66 | <!-- prepending -->
67 | <div class="InputAddOn">
68 |   <span class="InputAddOn-item">…</span>
69 |   <input class="InputAddOn-field">
70 | </div>
71 | 
72 | <!-- both -->
73 | <div class="InputAddOn">
74 |   <span class="InputAddOn-item">…</span>
75 |   <input class="InputAddOn-field">
76 |   <button class="InputAddOn-item">…</button>
77 | </div>
78 | ```
79 | 
80 | ## The CSS
81 | 
82 | ```css
83 | .InputAddOn {
84 |   display: flex;
85 | }
86 | 
87 | .InputAddOn-field {
88 |   flex: 1;
89 |   /* field styles */
90 | }
91 | 
92 | .InputAddOn-item {
93 |   /* item styles */
94 | }
95 | 
96 | ```
97 | 
98 | View the full [source](https://github.com/philipwalton/solved-by-flexbox/blob/master/assets/css/components/input-add-on.css) for the `InputAddOn` component used in this demo on Github.
99 | 


--------------------------------------------------------------------------------
/demos/media-object.md:
--------------------------------------------------------------------------------
  1 | ---
  2 | template: default.html
  3 | title: Media Object
  4 | excerpt: Create media objects with fixed or varying figure sizes without worrying about overflow, clearfixing, or block formatting context hacks.
  5 | ---
  6 | 
  7 | The [media object](http://www.stubbornella.org/content/2010/06/25/the-media-object-saves-hundreds-of-lines-of-code) is the poster-child of Object Oriented CSS</a> (OOCSS). Its simplicity and utility have converted many a CSS developer (myself included) to the OOCSS methodology.
  8 | 
  9 | But like most CSS layout techniques, the media object must resort to tricks and hacks to accomplish its goals.
 10 | 
 11 | The media object's body must prevent text from wrapping below the image by either creating a [block formatting context](http://www.stubbornella.org/content/2013/07/31/re-visiting-the-secret-power-of-block-fomatting-context/) or using a left margin/padding equal to the width of the image. The media object must also clearfix its body which requires either `overflow:hidden` or having to use the pseudo-elements.
 12 | 
 13 | With Flexbox these problems are solved. In addition, Flexbox allows us to vertically align the media object figure however we want. We can also easily align the figure to the right without needing to change the source order.
 14 | 
 15 | ## Basic Examples
 16 | 
 17 | <div class="Grid Grid--guttersLg Grid--full large-Grid--fit">
 18 |   <div class="Grid-cell">
 19 |     <div class="Demo Demo--spaced">
 20 |       <div class="Media">
 21 |         <img class="Media-figure Image" src="{{ site.baseUrl }}images/kitten.jpg" alt="Kitten">
 22 |         <div class="Media-body">
 23 |           <h3 class="Media-title">Standard Media Object</h3>
 24 |           <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur ac nisl quis massa vulputate adipiscing. Vivamus sit amet risus ligula. Nunc eu pulvinar augue.</p>
 25 |         </div>
 26 |       </div>
 27 |     </div>
 28 |     <div class="Demo Demo--spaced">
 29 |       <div class="Media">
 30 |         <img class="Media-figure Image" src="{{ site.baseUrl }}images/kitten.jpg" alt="Kitten">
 31 |         <div class="Media-body">
 32 |           <h3 class="Media-title">Standard Media Object</h3>
 33 |           <p>Donec imperdiet sem leo, id rutrum risus aliquam vitae. Cras tincidunt porta mauris, vel feugiat mauris accumsan eget.</p>
 34 |         </div>
 35 |       </div>
 36 |     </div>
 37 |   </div>
 38 |   <div class="Grid-cell">
 39 |     <div class="Demo Demo--spaced">
 40 |       <div class="Media Media--reverse">
 41 |         <img class="Media-figure Image" src="{{ site.baseUrl }}images/kitten.jpg" alt="Kitten">
 42 |         <div class="Media-body">
 43 |           <h3 class="Media-title">Media Object Reversed</h3>
 44 |           <p>Phasellus vel felis purus. Aliquam consequat pellentesque dui, non mollis erat dictum sit amet. Curabitur non quam dictum, consectetur arcu in, vehicula justo. Donec tortor massa, eleifend nec viverra in, aliquet at eros. Mauris laoreet condimentum mauris, non tempor massa fermentum ut. Integer gravida pharetra cursus. Nunc in suscipit nunc.</p>
 45 |         </div>
 46 |       </div>
 47 |     </div>
 48 |   </div>
 49 | </div>
 50 | 
 51 | ## Non-images
 52 | 
 53 | <div class="Grid Grid--guttersLg Grid--full large-Grid--fit">
 54 |   <div class="Grid-cell">
 55 |     <div class="Demo Demo--spaced">
 56 |       <div class="Media">
 57 |         <figure class="Media-figure"><span class="icon-comments icon-big"></span></figure>
 58 |         <div class="Media-body">
 59 |           <h3 class="Media-title">Using Icons</h3>
 60 |           <p>Donec imperdiet sem leo, id rutrum risus aliquam vitae. Vestibulum ac turpis non lacus dignissim dignissim eu sed dui.</p>
 61 |         </div>
 62 |       </div>
 63 |     </div>
 64 |   </div>
 65 |   <div class="Grid-cell">
 66 |     <div class="Demo Demo--spaced">
 67 |       <div class="Media Media--center">
 68 |         <figure class="Media-figure"><span class="icon-info-sign icon-big"></span></figure>
 69 |         <div class="Media-body">
 70 |           <h3 class="Media-title">Vertically Centering the Figure</h3>
 71 |           <p>Nunc nec fermentum dolor. Duis at iaculis turpis. Sed rutrum elit ac egestas dapibus. Duis nec consequat enim.</p>
 72 |         </div>
 73 |       </div>
 74 |     </div>
 75 |   </div>
 76 | </div>
 77 | 
 78 | ## Nested Media Objects
 79 | 
 80 | <div class="Grid Grid--guttersLg Grid--full large-Grid--fit">
 81 |   <div class="Grid-cell">
 82 |     <div class="Demo Demo--spaced">
 83 |       <div class="Media">
 84 |         <img class="Media-figure Image" src="{{ site.baseUrl }}images/kitten.jpg" alt="Kitten">
 85 |         <div class="Media-body">
 86 |           <h3 class="Media-title">Media Object Title</h3>
 87 |           <p>Phasellus vel felis purus. Aliquam consequat pellentesque dui, non mollis erat dictum sit amet. Curabitur non quam dictum, consectetur arcu in, vehicula justo.</p>
 88 |           <div class="Demo Demo--spaced u-smaller">
 89 |             <div class="Media">
 90 |               <figure class="Media-figure">
 91 |                 <img class="Image Image--tiny" src="{{ site.baseUrl }}images/kitten.jpg" alt="Kitten">
 92 |               </figure>
 93 |               <p class="Media-body">
 94 |                 Mauris porta arcu id magna adipiscing lacinia at congue lacus. Vivamus blandit quam quis tincidunt egestas. Etiam posuere lectus sed sapien malesuada molestie.
 95 |               </p>
 96 |             </div>
 97 |           </div>
 98 |           <div class="Demo Demo--spaced u-smaller">
 99 |             <div class="Media">
100 |               <figure class="Media-figure">
101 |                 <img class="Image Image--tiny" src="{{ site.baseUrl }}images/kitten.jpg" alt="Kitten">
102 |               </figure>
103 |               <div class="Media-body">
104 |                 <p>Vestibulum ac turpis non lacus dignissim dignissim eu sed dui. Proin a ligula sit amet massa malesuada mattis eu a ante. Nunc porttitor sed quam quis sollicitudin. Vestibulum ac turpis non lacus dignissim dignissim eu sed dui.</p>
105 |                 <div class="Media Media--center">
106 |                   <span class="Media-figure icon-thumbs-up-alt"></span>
107 |                   <p class="Media-body">Rutrum risus aliquam vitae.</p>
108 |                 </div>
109 |               </div>
110 |             </div>
111 |           </div>
112 |         </div>
113 |       </div>
114 |     </div>
115 |   </div>
116 | 
117 |   <div class="Grid-cell">
118 |     <div class="Demo Demo--spaced">
119 |       <div class="Media">
120 |         <img class="Media-figure Image" src="{{ site.baseUrl }}images/kitten.jpg" alt="Kitten">
121 |         <div class="Media-body">
122 |           <h3 class="Media-title">Media Object Title</h3>
123 |           <p>Phasellus vel felis purus. Aliquam consequat pellentesque dui, non mollis erat dictum sit amet. Curabitur non quam dictum, consectetur arcu in, vehicula justo. Donec tortor massa, eleifend nec viverra in, aliquet at eros. Mauris laoreet condimentum mauris, non tempor massa fermentum ut.</p>
124 |           <div class="Media Media--center u-smaller">
125 |             <span class="Media-figure icon-thumbs-up-alt"></span>
126 |             <p class="Media-body">Donec imperdiet sem leo, id rutrum risus aliquam vitae.</p>
127 |           </div>
128 |           <div class="Demo Demo--spaced u-smaller">
129 |             <div class="Media">
130 |               <figure class="Media-figure">
131 |                 <img class="Image Image--tiny" src="{{ site.baseUrl }}images/kitten.jpg" alt="Kitten">
132 |               </figure>
133 |               <p class="Media-body">
134 |                 Mauris porta arcu id magna adipiscing lacinia at congue lacus. Vivamus blandit quam quis tincidunt egestas. Etiam posuere lectus sed sapien malesuada molestie. Aliquam vitae pharetra dolor. Nullam non mattis nunc.
135 |               </p>
136 |             </div>
137 |           </div>
138 |         </div>
139 |       </div>
140 |     </div>
141 |   </div>
142 | </div>
143 | 
144 | ## The HTML
145 | 
146 | ```html
147 | <div class="Media">
148 |   <img class="Media-figure" src="" alt="">
149 |   <p class="Media-body">&hellip;</p>
150 | </div>
151 | ```
152 | 
153 | ## The CSS
154 | 
155 | ```css
156 | .Media {
157 |   display: flex;
158 |   align-items: flex-start;
159 | }
160 | 
161 | .Media-figure {
162 |   margin-right: 1em;
163 | }
164 | 
165 | .Media-body {
166 |   flex: 1;
167 | }
168 | ```
169 | 
170 | View the full [source](https://github.com/philipwalton/solved-by-flexbox/blob/master/assets/css/components/media.css) for the `Media` component used in this demo on Github.
171 | 


--------------------------------------------------------------------------------
/demos/sticky-footer.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | template: default.html
 3 | title: Sticky Footer
 4 | excerpt: Getting your footer to stick to the bottom of sparsely contented pages has always been tricky. And if the footer's height is unknown, it's basically impossible. Not so anymore.
 5 | ---
 6 | 
 7 | <div class="Demo Demo--spaced">
 8 | 
 9 | Click the button below to hide the contents of this page. Notice how the footer sticks to the bottom of the window even when there's not enough content to fill the page.
10 | 
11 | <button id="collapse-trigger" class="Button"><span class="icon-refresh u-spaceRS"></span> Toggle Contents</button>
12 | 
13 | </div>
14 | 
15 | <div id="collapsable-content">
16 | 
17 | Getting the footer to stick to the bottom of pages with sparse content is something just about every Web developer has tried to tackle at some point in his or her career. And, for the most part, it's a solved problem. Yet all the [existing solutions](http://ryanfait.com/resources/footer-stick-to-bottom-of-page/) have one significant shortcoming &mdash; they don't work if the height of your footer is unknown.
18 | 
19 | Flexbox is a perfect fit for this type of problem. While mostly known for laying out content in the horizontal direction, Flexbox actually works just as well for vertical layout problems. All you have to do is wrap the vertical sections in a flex container and choose which ones you want to expand. They'll automatically take up all the available space in their container.
20 | 
21 | In the example below, the container is set to the height of the window, and the content area is told to expand as needed. *(Note: in the vertical direction you need to specify a height for the container. This is different from the horizontal direction, which automatically expands to fit.)*
22 | 
23 | ## The HTML
24 | 
25 | ```xml
26 | <body class="Site">
27 |   <header>…</header>
28 |   <main class="Site-content">…</main>
29 |   <footer>…</footer>
30 | </body>
31 | ```
32 | 
33 | ## The CSS
34 | 
35 | ```css
36 | .Site {
37 |   display: flex;
38 |   min-height: 100vh;
39 |   flex-direction: column;
40 | }
41 | 
42 | .Site-content {
43 |   flex: 1;
44 | }
45 | ```
46 | 
47 | View the full [source](https://github.com/philipwalton/solved-by-flexbox/blob/master/assets/css/components/site.css) for the `Site` component used in this demo on Github.
48 | 
49 | <aside class="Notice"><strong>Note:</strong>&nbsp; the CSS required to make this demo work cross-browser is slightly different from the CSS shown in the example above, which assumes a fully spec-compliant browser. See the <a href="https://github.com/philipwalton/solved-by-flexbox/blob/master/assets/css/components/site.css">comments in the source</a> for more details.</aside>
50 | 
51 | </div>
52 | 
53 | <script class="js-allow-before-footer">
54 |   (function() {
55 |     var collapseTrigger = document.getElementById("collapse-trigger");
56 |     var collapseableContent = document.getElementById("collapsable-content");
57 |     var isCollapsed = false;
58 |     collapseTrigger.addEventListener("click", function() {
59 |       if (isCollapsed) {
60 |         collapseableContent.classList.remove("u-hidden");
61 |       } else {
62 |         collapseableContent.classList.add("u-hidden");
63 |       }
64 |       isCollapsed = !isCollapsed;
65 |     }, false);
66 |   }());
67 | </script>
68 | 


--------------------------------------------------------------------------------
/demos/vertical-centering.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | template: default.html
 3 | title: Vertical Centering
 4 | excerpt: This classic problem has been challenging CSS hackers for years, yet none of the historical solutions have fully solved it. With Flexbox, it's finally possible.
 5 | ---
 6 | 
 7 | The lack of good ways to vertically center elements in CSS has been a dark blemish on its reputation for pretty much its entire existence.
 8 | 
 9 | What makes matters worse is the techniques that do work for vertical centering are obscure and unintuitive, while the obvious choices (like `vertical-align:middle`) never seem to work when you need them.
10 | 
11 | The current landscape of [vertical centering options](http://css-tricks.com/centering-in-the-unknown/) ranges from negative margins to `display:table-cell` to ridiculous hacks involving full-height pseudo-elements. Yet even though these techniques sometimes get the job done, they don't work in every situation. What if the thing you want to center is of unknown dimensions and isn't the only child of its parent? What if you could use the pseudo-element hack, but you need those pseudo-elements for something else?
12 | 
13 | With Flexbox, you can stop worrying. You can align anything (vertically or horizontally) quite painlessly with the `align-items`, `align-self`, and `justify-content` properties.
14 | 
15 | <div class="Demo Demo--spaced u-ieMinHeightBugFix">
16 |   <div class="Aligner">
17 |     <div class="Aligner-item Aligner-item--fixed">
18 |       <div class="Demo">
19 |         <h3>I'm Centered!</h3>
20 |         <p contenteditable="true">This box is both vertically and horizontally centered. Even if the text in this box changes to make it wider or taller, the box will still be centered. Go ahead, give it a try. Just click to edit the text.</p>
21 |       </div>
22 |     </div>
23 |   </div>
24 | </div>
25 | 
26 | Unlike some of the existing vertical alignment techniques, with Flexbox the presence of sibling elements doesn't affect their ability to be vertically aligned.
27 | 
28 | <div class="Demo Demo--spaced u-ieMinHeightBugFix">
29 |   <div class="Aligner">
30 |     <div class="Aligner-item Aligner-item--top">
31 |       <div class="Demo"><strong>Top</strong></div>
32 |     </div>
33 |     <div class="Aligner-item">
34 |       <div class="Demo"><strong>Centered</strong></div>
35 |     </div>
36 |     <div class="Aligner-item Aligner-item--bottom">
37 |       <div class="Demo"><strong>Bottom</strong></div>
38 |     </div>
39 |   </div>
40 | </div>
41 | 
42 | ## The HTML
43 | 
44 | ```html
45 | <div class="Aligner">
46 |   <div class="Aligner-item Aligner-item--top">…</div>
47 |   <div class="Aligner-item">…</div>
48 |   <div class="Aligner-item Aligner-item--bottom">…</div>
49 | </div>
50 | ```
51 | 
52 | ## The CSS
53 | 
54 | ```css
55 | .Aligner {
56 |   display: flex;
57 |   align-items: center;
58 |   justify-content: center;
59 | }
60 | 
61 | .Aligner-item {
62 |   max-width: 50%;
63 | }
64 | 
65 | .Aligner-item--top {
66 |   align-self: flex-start;
67 | }
68 | 
69 | .Aligner-item--bottom {
70 |   align-self: flex-end;
71 | }
72 | ```
73 | 
74 | View the full [source](https://github.com/philipwalton/solved-by-flexbox/blob/master/assets/css/components/aligner.css) for the `Aligner` component used in this demo on Github.
75 | 
76 | <aside class="Notice"><strong>Note:</strong>&nbsp; the markup and CSS required to make this demo work cross-browser is slightly different from what's shown in the examples above, which assume a fully spec-compliant browser. See the <a href="https://github.com/philipwalton/solved-by-flexbox/blob/master/assets/css/utils/compat.css">comments in the source</a> for more details.</aside>
77 | 


--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
  1 | const connect = require('connect');
  2 | const cssnano = require('cssnano');
  3 | const fs = require('fs-extra');
  4 | const frontMatter = require('front-matter');
  5 | const globby = require('globby');
  6 | const gulp = require('gulp');
  7 | const he = require('he');
  8 | const hljs = require('highlight.js');
  9 | const htmlMinifier = require('html-minifier');
 10 | const MarkdownIt = require('markdown-it');
 11 | const nunjucks = require('nunjucks');
 12 | const path = require('path');
 13 | const postcss = require('postcss');
 14 | const atImport = require('postcss-import');
 15 | const postcssPresetEnv = require('postcss-preset-env');
 16 | const serveStatic = require('serve-static');
 17 | const sh = require('shelljs');
 18 | const {argv} = require('yargs');
 19 | 
 20 | const isProd = () => process.env.NODE_ENV == 'production';
 21 | 
 22 | /**
 23 |  * The output directory for all the built files.
 24 |  */
 25 | const DEST = './solved-by-flexbox';
 26 | 
 27 | /**
 28 |  * The base public path of the site.
 29 |  */
 30 | const PUBLIC_PATH = path.join('/', DEST, '/');
 31 | 
 32 | nunjucks.configure('templates', {autoescape: false, noCache: true});
 33 | 
 34 | /**
 35 |  * Renders markdown content as HTML with syntax highlighted code blocks.
 36 |  * @param {string} content A markdown string.
 37 |  * @return {string} The rendered HTML.
 38 |  */
 39 | const renderMarkdown = (content) => {
 40 |   const md = new MarkdownIt({
 41 |     html: true,
 42 |     typographer: true,
 43 |     highlight: (code, lang) => {
 44 |       code = lang ? hljs.highlight(lang, code).value :
 45 |           // Since we're not using highlight.js here, we need to
 46 |           // espace the html, but we have to unescape first in order
 47 |           // to avoid double escaping.
 48 |           he.escape(he.unescape(code));
 49 | 
 50 |       return code;
 51 |     },
 52 |   });
 53 | 
 54 |   return md.render(content);
 55 | };
 56 | 
 57 | gulp.task('pages', async () => {
 58 |   const baseData = await fs.readJSON('./config.json');
 59 |   const overrides = {
 60 |     baseUrl: PUBLIC_PATH,
 61 |     env: process.env.NODE_ENV || 'development'
 62 |   };
 63 |   const site = Object.assign({demos: []}, baseData, overrides);
 64 | 
 65 |   const processContent = async (pagePath) => {
 66 |     const slug = path.basename(pagePath, path.extname(pagePath));
 67 |     const permalink = site.baseUrl +
 68 |         (slug === 'index' ? '' : 'demos/' + slug + '/');
 69 | 
 70 |     const fileContents = await fs.readFile(pagePath, 'utf-8');
 71 |     const {body, attributes} = frontMatter(fileContents);
 72 | 
 73 |     const data = {
 74 |       site,
 75 |       page: {
 76 |         content: body,
 77 |         slug,
 78 |         permalink,
 79 |         ...attributes,
 80 |       },
 81 |     };
 82 | 
 83 |     if (path.extname(pagePath) == '.md') {
 84 |       data.page.content = renderMarkdown(data.page.content);
 85 |     }
 86 |     data.page.content = nunjucks.renderString(data.page.content, data);
 87 | 
 88 |     return data;
 89 |   }
 90 | 
 91 |   const renderPage = async (data) => {
 92 |     let html = nunjucks.render(data.page.template, data);
 93 |     if (process.env.NODE_ENV === 'production') {
 94 |       html = htmlMinifier.minify(html, {
 95 |         removeComments: true,
 96 |         collapseWhitespace: true,
 97 |         collapseBooleanAttributes: true,
 98 |         removeAttributeQuotes: true,
 99 |         removeRedundantAttributes: true,
100 |         useShortDoctype: true,
101 |         removeEmptyAttributes: true,
102 |         minifyJS: true,
103 |         minifyCSS: true,
104 |       });
105 |     };
106 | 
107 |     const outputPath = path.join(data.page.permalink.slice(1), 'index.html');
108 |     await fs.outputFile(outputPath, html);
109 |   };
110 | 
111 |   const demoPaths = await globby('./demos/**/*');
112 |   for (const demoPath of demoPaths) {
113 |     const data = await processContent(demoPath);
114 | 
115 |     // Add the page data to the site demos.
116 |     site.demos.push(data.page);
117 | 
118 |     await renderPage(data);
119 |   };
120 | 
121 |   const pagePaths = await globby('*.html');
122 |   for (const pagePath of pagePaths) {
123 |     const data = await processContent(pagePath);
124 |     await renderPage(data);
125 |   };
126 | });
127 | 
128 | gulp.task('images', () => {
129 |   return gulp.src('./assets/images/**/*')
130 |       .pipe(gulp.dest(path.join(DEST, 'images')));
131 | });
132 | 
133 | gulp.task('css', async () => {
134 |   const src = './assets/css/main.css';
135 |   const css = await fs.readFile(src, 'utf-8');
136 | 
137 |   const plugins = [
138 |     atImport(),
139 |     postcssPresetEnv({
140 |       stage: 0,
141 |       browsers: '> 1%, last 2 versions, Safari > 5, ie > 9, Firefox ESR',
142 |     }),
143 |   ];
144 |   if (process.env.NODE_ENV === 'production') {
145 |     plugins.push(cssnano({
146 |       preset: ['default', {discardComments: {removeAll: true}}],
147 |     }));
148 |   }
149 | 
150 |   const result = await postcss(plugins).process(css, {from: src});
151 |   await fs.outputFile(path.join(DEST, path.basename(src)), result.css);
152 | });
153 | 
154 | gulp.task('javascript', async () => {
155 |   await sh.exec('rollup -c');
156 | });
157 | 
158 | gulp.task('default', gulp.parallel('css', 'images', 'javascript', 'pages'));
159 | 
160 | gulp.task('serve', gulp.series('default', () => {
161 |   let port = argv.port || argv.p || 4000;
162 |   connect().use(serveStatic('./')).listen(port);
163 | 
164 |   gulp.watch('./assets/css/**/*.css', gulp.series('css'));
165 |   gulp.watch('./assets/images/*', gulp.series('images'));
166 |   gulp.watch('./assets/main.js', gulp.series('javascript'));
167 |   gulp.watch(['*.html', './demos/*', './templates/*'], gulp.series('pages'));
168 | }));
169 | 
170 | gulp.task('deploy', gulp.series('default', (done) => {
171 |   if (process.env.NODE_ENV != 'production') {
172 |     throw new Error('Deploying requires NODE_ENV to be set to production');
173 |   }
174 | 
175 |   const repoUrl = 'git@github.com:philipwalton/solved-by-flexbox.git';
176 | 
177 |   // Create a temporary directory and
178 |   // checkout the existing gh-pages branch.
179 |   sh.rm('-rf', '_tmp');
180 |   sh.mkdir('_tmp');
181 |   sh.cd('_tmp');
182 |   sh.exec('git init');
183 |   sh.exec('git remote add origin ' + repoUrl);
184 |   sh.exec('git pull origin gh-pages');
185 | 
186 |   // Delete all the existing files and add
187 |   // the new ones from the build directory.
188 |   sh.rm('-rf', './*');
189 |   sh.cp('-rf', path.join('..', DEST, '/*'), './');
190 |   sh.exec('git add -A');
191 | 
192 |   // Commit and push the changes to
193 |   // the gh-pages branch.
194 |   sh.exec('git commit -m "Deploy site"');
195 |   sh.exec('git branch -m gh-pages');
196 |   sh.exec('git push origin gh-pages');
197 | 
198 |   // Clean up.
199 |   sh.cd('..');
200 |   sh.rm('-rf', '_tmp');
201 |   sh.rm('-rf', DEST);
202 | 
203 |   done();
204 | }));
205 | 


--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
  1 | ---
  2 | template: home.html
  3 | ---
  4 | 
  5 | <section class="Section">
  6 |   <div class="Container">
  7 |     <h2 class="Section-heading">Introduction</h2>
  8 |     <p>CSS has been lacking proper layout mechanisms for far too long. Transitions, animations, filters, all of these are great and useful additions to the language, but they don't address the major problems that Web developers have been complaining about for what seems like an eternity.</p>
  9 |     <p>Finally, thanks to <a href="http://www.w3.org/TR/css3-flexbox/">Flexbox</a>, we have a solution.</p>
 10 |     <p>This site is not another CSS framework. Instead, its purpose is to showcase problems once hard or impossible to solve with CSS alone, now made trivially easy with Flexbox. With the release of Internet Explorer 11 and Safari 6.1, the latest Flexbox spec is now supported in every modern browser.</p>
 11 |     <p>Check out the demos below. View the styles in the Web inspector or dive into <a href="https://github.com/philipwalton/solved-by-flexbox">the source</a> to see just how easy CSS layout becomes with Flexbox.</p>
 12 |   </div>
 13 | </section>
 14 | 
 15 | <section class="Section">
 16 |   <div class="Container">
 17 |     <h2 class="Section-heading">Showcase</h2>
 18 |     <ul class="Grid Grid--guttersLg">
 19 |       {% for demo in site.demos %}
 20 |         <li class="Grid-cell u-full u-med-1of2 u-large-1of3">
 21 |           <div class="Feature">
 22 |             <a href="{{ site.baseUrl }}demos/{{ demo.slug }}/">
 23 |               <figure class="Feature-figure">
 24 |                 <img class="Feature-image" alt="{{ demo.title }}" src="{{ site.baseUrl }}images/{{ demo.slug }}.jpg">
 25 |               </figure>
 26 |               <h3 class="Feature-title">{{ demo.title }}</h3>
 27 |             </a>
 28 |             <p class="Feature-description">{{ demo.excerpt }}</p>
 29 |           </div>
 30 |         </li>
 31 |       {% endfor %}
 32 |     </ul>
 33 |   </div>
 34 | </section>
 35 | 
 36 | <section class="Section">
 37 |   <div class="Container">
 38 |     <h2 class="Section-heading">Browser Support</h2>
 39 | 
 40 |     <ul class="Grid Grid--guttersLg Grid--justifyCenter">
 41 |       <li class="Grid-cell Grid-cell--autoSize">
 42 |         <div class="Browser Browser--chrome" title="Since 2012-07-31">
 43 |           <figure class="Browser-image"></figure>
 44 |           Chrome<br>21+
 45 |         </div>
 46 |       </li>
 47 |       <li class="Grid-cell Grid-cell--autoSize">
 48 |         <div class="Browser Browser--opera" title="Since 2012-11-05">
 49 |           <figure class="Browser-image"></figure>
 50 |           Opera<br>12.1+
 51 |         </div>
 52 |       </li>
 53 |       <li class="Grid-cell Grid-cell--autoSize">
 54 |         <div class="Browser Browser--firefox" title="Since 2013-06-25">
 55 |           <figure class="Browser-image"></figure>
 56 |           Firefox<br>22+
 57 |         </div>
 58 |       </li>
 59 |       <li class="Grid-cell Grid-cell--autoSize">
 60 |         <div class="Browser Browser--safari" title="Since 2013-06-11">
 61 |           <figure class="Browser-image"></figure>
 62 |           Safari<br>6.1+
 63 |         </div>
 64 |       </li>
 65 |       <li class="Grid-cell Grid-cell--autoSize">
 66 |         <div class="Browser Browser--ie" title="Since 2012-09-04">
 67 |           <figure class="Browser-image"></figure>
 68 |           IE<br>10+
 69 |         </div>
 70 |       </li>
 71 |       <li class="Grid-cell Grid-cell--autoSize">
 72 |         <div class="Browser Browser--edge" title="Since 2015-03-15">
 73 |           <figure class="Browser-image"></figure>
 74 |           Edge<br>All
 75 |         </div>
 76 |       </li>
 77 |     </ul>
 78 | 
 79 |     <h3 class="Section-heading">Caveats and Known Issues</h3>
 80 |     <ul class="Section-list">
 81 |       <li>IE 10 has Flexbox support but for a <a href="http://www.w3.org/TR/2012/WD-css3-flexbox-20120322/">draft version</a> of the current spec: (<code>display:flexbox</code>).</li>
 82 |       <li>For a full browser support comparison, check out <a href="http://caniuse.com/flexbox">caniuse.com/flexbox</a></li>
 83 |     </ul>
 84 |   </div>
 85 | </section>
 86 | 
 87 | <section class="Section">
 88 |   <div class="Container">
 89 |     <h2 class="Section-heading">About the Code</h2>
 90 |     <p>All of the code samples on this site show how to solve a particular design problem with Flexbox. They show just the code that's needed to make the demos work in a spec-compliant browser. Some browsers do not fully comply with the latest version of the spec, so sadly, a few workarounds were necessary.</p>
 91 |     <p>Workarounds for non-compliant browsers are not shown in the code samples, but if you're curious about those implementation details, you can check out the source files. Each demo links to its source, and all browser-specific workarounds are well-documented, so don't be afraid to take a look.</p>
 92 |     <p>The vendor prefixing and translating of current flex properties to their legacy equivalents is all handled by <a href="https://github.com/ai/autoprefixer">autoprefixer</a>. If you're writing Flexbox code and not using autoprefixer, well, you're making a horrible mistake.</p>
 93 |     <p>The class naming convention used in the code samples and source files is taken from <a href="https://github.com/suitcss/suit">SUIT CSS</a>, which is based on BEM methodologies. Each example includes one or more reusable CSS components allowing you to adapt or copy these patterns in to your own projects. Links are provided to their respective components on each example page.</p>
 94 |     <p>If you find a mistake or would like to suggest an additional example, feel free to open an issue or submit a pull request on <a href="https://github.com/philipwalton/solved-by-flexbox">Github</a>.</p>
 95 |   </div>
 96 | </section>
 97 | <section class="Section">
 98 |   <div class="Container">
 99 |     <h2 class="Section-heading">Translations</h2>
100 |     <p>The following translations have been graciously provided by the community:</p>
101 |     <ul class="Section-list">
102 |       <li><a href="https://hufan-akari.github.io/solved-by-flexbox/">Chinese</a></li>
103 |       <li><a href="http://hashrock.github.io/solved-by-flexbox-ja/">Japanese</a></li>
104 |       <li><a href="https://hyunseob.github.io/solved-by-flexbox-kr/">Korean</a></li>
105 |     </ul>
106 |     <p>Please note that translations are unofficial and may be inaccurate or out of date. To submit your own translation, please submit a <a href="https://github.com/philipwalton/solved-by-flexbox/pull/new/master" class="rich-diff-level-one">pull request</a> or <a href="https://github.com/philipwalton/solved-by-flexbox/issues/new" class="rich-diff-level-one">open an issue</a> on GitHub and link to your translated content.</p>
107 |   </div>
108 | </section>
109 | 


--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "name": "solved-by-flexbox",
 3 |   "description": "A showcase of problems once hard or impossible to solve with CSS alone, now made trivially easy with Flexbox.",
 4 |   "homepage": "https://philipwalton.github.io/solved-by-flexbox",
 5 |   "repository": {
 6 |     "type": "git",
 7 |     "url": "https://github.com/philipwalton/solved-by-flexbox.git"
 8 |   },
 9 |   "license": "MIT",
10 |   "scripts": {
11 |     "build": "gulp",
12 |     "start": "gulp serve",
13 |     "deploy": "rm -rf solved-by-flexbox && NODE_ENV=production gulp deploy"
14 |   },
15 |   "devDependencies": {
16 |     "@rollup/plugin-node-resolve": "^11.0.0",
17 |     "autoprefixer": "^10.0.4",
18 |     "connect": "^3.7.0",
19 |     "cssnano": "^4.1.10",
20 |     "dot-prop": ">=4.2.1",
21 |     "front-matter": "^4.0.2",
22 |     "fs-extra": "^9.0.1",
23 |     "globby": "^11.0.1",
24 |     "gulp": "^4.0.2",
25 |     "he": "^1.2.0",
26 |     "highlight.js": "^10.4.0",
27 |     "html-minifier": "^4.0.0",
28 |     "markdown-it": "^12.0.2",
29 |     "normalize.css": "^8.0.1",
30 |     "nunjucks": "3.2.2",
31 |     "postcss": "^8.1.10",
32 |     "postcss-import": "^13.0.0",
33 |     "postcss-preset-env": "^6.7.0",
34 |     "rollup": "^2.34.0",
35 |     "rollup-plugin-terser": "^7.0.2",
36 |     "serve-static": "^1.14.1",
37 |     "shelljs": "^0.8.4",
38 |     "suitcss-utils-display": "^1.0.2",
39 |     "suitcss-utils-text": "^1.0.0",
40 |     "web-vitals": "^1.0.1",
41 |     "yargs": "^16.1.1"
42 |   }
43 | }
44 | 


--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
 1 | import nodeResolve from '@rollup/plugin-node-resolve';
 2 | import {terser} from 'rollup-plugin-terser';
 3 | 
 4 | const plugins = [
 5 |   nodeResolve(),
 6 | ]
 7 | 
 8 | if (process.env.NODE_ENV === 'production') {
 9 |   plugins.push(terser({module: true}));
10 | }
11 | 
12 | export default {
13 |   plugins,
14 |   input: 'assets/main.js',
15 |   output: {
16 |     dir: 'solved-by-flexbox',
17 |     format: 'esm',
18 |   },
19 | };
20 | 


--------------------------------------------------------------------------------
/templates/default.html:
--------------------------------------------------------------------------------
 1 | <!DOCTYPE html>
 2 | <html lang="en">
 3 |   {% include 'head.html' %}
 4 |   <body class="Site">
 5 |     <header class="Site-header">
 6 |       <div class="Header Header--cozy" role="banner">
 7 |         {% include 'header.html' %}
 8 |       </div>
 9 |     </header>
10 |     <main class="Site-content">
11 |       <div class="Container">
12 |         <h1>{{ page.title }}</h1>
13 |         {{ page.content }}
14 |       </div>
15 |     </main>
16 |     <footer class="Site-footer">
17 |       <div class="Footer">
18 |         {% include 'footer.html' %}
19 |       </div>
20 |     </footer>
21 |     {% include 'scripts.html' %}
22 |   </body>
23 | </html>
24 | 


--------------------------------------------------------------------------------
/templates/footer.html:
--------------------------------------------------------------------------------
 1 | <span class="Footer-social">
 2 |   <a class="github-button" href="https://github.com/philipwalton/solved-by-flexbox" data-icon="octicon-star" data-show-count="true" aria-label="Star philipwalton/solved-by-flexbox on GitHub">Star</a>
 3 |   <a href="https://twitter.com/philwalton" class="twitter-follow-button" data-show-count="true" data-lang="en">@philwalton</a>
 4 |   <a href="https://twitter.com/share" class="twitter-share-button" data-text="A showcase of traditionally hard CSS problems, easily solved using flexbox." data-url="https://philipwalton.github.io/solved-by-flexbox/" data-count="horizontal" data-via="philwalton" data-related="philwalton:Creator of Solved by Flexbox">Tweet</a>
 5 | </span>
 6 | <div class="Footer-credits">
 7 |   <span class="Footer-credit">Created and maintained by <a href="https://philipwalton.com">Philip Walton</a>.</span>
 8 |   <span class="Footer-credit">Source code and examples released under the <a href="https://github.com/philipwalton/solved-by-flexbox/blob/master/LICENSE">MIT</a> license.</span>
 9 |   <span class="Footer-credit">Website and documentation licensed under <a href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a>.</span>
10 | </div>
11 | 


--------------------------------------------------------------------------------
/templates/head.html:
--------------------------------------------------------------------------------
 1 | <head>
 2 |   <meta charset="utf-8">
 3 |   <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
 4 | 
 5 |   <title>{% if page.title %}{{ page.title }} &mdash; {% endif %}{{ site.title }} &mdash; {{ site.tagline }}</title>
 6 | 
 7 |   <meta name="HandheldFriendly" content="True">
 8 |   <meta name="MobileOptimized" content="320">
 9 |   <meta name=viewport content="width=device-width, minimum-scale=1.0, maximum-scale=1.0">
10 |   <meta name="description" content="{{ site.description }}">
11 |   <meta name="google-site-verification" content="q5KncOje-dNdD5uxqSOG1znSAo5Wsz5MlBcAmteQAJA" />
12 | 
13 |   <link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600" rel="stylesheet">
14 | 
15 |   <link href="https://netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.min.css" rel="stylesheet">
16 |   <link href="{{ site.baseUrl }}main.css" rel="stylesheet" type="text/css">
17 | 
18 |   <!-- FID polyfill -->
19 |   <script>
20 |   !function(n,e){var t,o,i,c=[],f={passive:!0,capture:!0},r=new Date,a="pointerup",u="pointercancel";function p(n,c){t||(t=c,o=n,i=new Date,w(e),s())}function s(){o>=0&&o<i-r&&(c.forEach(function(n){n(o,t)}),c=[])}function l(t){if(t.cancelable){var o=(t.timeStamp>1e12?new Date:performance.now())-t.timeStamp;"pointerdown"==t.type?function(t,o){function i(){p(t,o),r()}function c(){r()}function r(){e(a,i,f),e(u,c,f)}n(a,i,f),n(u,c,f)}(o,t):p(o,t)}}function w(n){["click","mousedown","keydown","touchstart","pointerdown"].forEach(function(e){n(e,l,f)})}w(n),self.perfMetrics=self.perfMetrics||{},self.perfMetrics.onFirstInputDelay=function(n){c.push(n),s()}}(addEventListener,removeEventListener);
21 | </script>
22 | </head>
23 | 


--------------------------------------------------------------------------------
/templates/header.html:
--------------------------------------------------------------------------------
 1 | <div class="Header-titles">
 2 |   <h1 class="Header-title"><a href="{{ site.baseUrl }}">Solved <i>by</i> Flexbox</a></h1>
 3 |   <h2 class="Header-subTitle">{{ site.tagline }}</h2>
 4 | </div>
 5 | <div class="Header-actions">
 6 |   <a class="Header-button Button Button--action Button--wide"
 7 |      ga-on="click"
 8 |      ga-hit-type="social"
 9 |      ga-social-network="Github"
10 |      ga-social-action="view-source"
11 |      ga-social-target="https://github.com/philipwalton/solved-by-flexbox"
12 |      href="https://github.com/philipwalton/solved-by-flexbox">
13 |     <span class="icon-github icon-large"></span>&nbsp; View Project Source
14 |   </a>
15 |   <a class="Header-button Button Button--wide"
16 |      ga-on="click"
17 |      ga-hit-type="social"
18 |      ga-social-network="Twitter"
19 |      ga-social-action="tweet"
20 |      ga-social-target="https://philipwalton.github.io/solved-by-flexbox{{ page.permalink }}"
21 |      href="https://twitter.com/intent/tweet?text={{ 'A showcase of traditionally hard CSS problems, easily solved using flexbox.' | urlencode }}&url=https://philipwalton.github.io/solved-by-flexbox/&via=philwalton">
22 |     <span class="icon-twitter icon-large twitter-color"></span>&nbsp; Spread the Word
23 |   </a>
24 | </div>
25 | 


--------------------------------------------------------------------------------
/templates/holy-grail.html:
--------------------------------------------------------------------------------
 1 | <!DOCTYPE html>
 2 | <html lang="en">
 3 |   {% include 'head.html' %}
 4 |   <body class="HolyGrail">
 5 |     <header class="HolyGrail-header">
 6 |       <div class="Header Header--cozy" role="banner">
 7 |         {% include 'header.html' %}
 8 |       </div>
 9 |     </header>
10 |     <main class="HolyGrail-body">
11 |       <article class="HolyGrail-content">
12 |         <h1>{{ page.title }}</h1>
13 |         {{ page.content }}
14 |       </article>
15 |       <nav class="HolyGrail-nav u-textCenter">
16 |         <strong>Navigation</strong>
17 |       </nav>
18 |       <aside class="HolyGrail-ads u-textCenter">
19 |         <strong>Advertisements</strong>
20 |       </aside>
21 |     </main>
22 |     <footer class="HolyGrail-footer">
23 |       <div class="Footer">
24 |         {% include 'footer.html' %}
25 |       </div>
26 |     </footer>
27 |     {% include 'scripts.html' %}
28 |   </body>
29 | </html>
30 | 


--------------------------------------------------------------------------------
/templates/home.html:
--------------------------------------------------------------------------------
 1 | <!DOCTYPE html>
 2 | <html lang="en">
 3 |   {% include 'head.html' %}
 4 |   <body class="Site">
 5 |     <header class="Site-header">
 6 |       <div class="Header" role="banner">
 7 |         {% include 'header.html' %}
 8 |       </div>
 9 |     </header>
10 |     <main class="Site-content Site-content--full">
11 |       {{ page.content }}
12 |     </main>
13 |     <footer class="Site-footer">
14 |       <div class="Footer">
15 |         {% include 'footer.html' %}
16 |       </div>
17 |     </footer>
18 |     {% include 'scripts.html' %}
19 |   </body>
20 | </html>
21 | 


--------------------------------------------------------------------------------
/templates/scripts.html:
--------------------------------------------------------------------------------
 1 | <script>
 2 | (function() {
 3 |   var style = document.body.style;
 4 |   var supportsFlexbox = 'flexBasis' in style ||
 5 |       'msFlexAlign' in style || 'webkitBoxDirection' in style;
 6 | 
 7 |   if (!supportsFlexbox) {
 8 |     var div = document.createElement('div');
 9 |     div.className = 'Error';
10 |     div.innerHTML = 'Your browser does not support Flexbox.  ' +
11 |         'Parts of this site may not appear as expected.';
12 | 
13 |     document.body.insertBefore(div, document.body.firstChild);
14 |   }
15 | })();
16 | </script>
17 | 
18 | <script async src="https://www.googletagmanager.com/gtag/js?id=G-0YRDCZXZSB"></script>
19 | <script>
20 | window.dataLayer = window.dataLayer || [];
21 | function gtag(){dataLayer.push(arguments);}
22 | gtag('js', new Date());
23 | var config = {
24 |   measurement_version: '5',
25 |   transport_type: 'beacon',
26 |   debug_mode: location.hostname !== 'philipwalton.github.io',
27 |   custom_map: {
28 |     dimension1: 'measurement_version',
29 |     dimension2: 'event_id',
30 |   },
31 | };
32 | gtag('config', 'UA-40829935-1', config);
33 | gtag('config', 'G-0YRDCZXZSB', config);
34 | </script>
35 | 
36 | <script type="module" src="{{ site.baseUrl }}main.js"></script>
37 | 
38 | <script defer id="twitter-wjs" src="https://platform.twitter.com/widgets.js"></script>
39 | <script defer src="https://buttons.github.io/buttons.js"></script>


--------------------------------------------------------------------------------