├── .babelrc ├── .gitignore ├── .nojekyll ├── README.html ├── README.md ├── docs ├── app.css ├── app.js ├── background-image │ └── index.html ├── base │ └── index.html ├── baseline │ └── index.html ├── boxmodel │ └── index.html ├── centering │ └── index.html ├── clearing-floats │ └── index.html ├── columns │ └── index.html ├── display │ └── index.html ├── examples │ ├── background-image.html │ ├── baseline.html │ ├── boxmodel.html │ ├── centering.html │ ├── clearing-floats.html │ ├── columns.html │ ├── display.html │ ├── floating.html │ ├── forms.html │ ├── grids.html │ ├── intro.html │ ├── no-bootstrap.html │ ├── other.html │ ├── positioning.html │ ├── pseudoelements.html │ ├── selectors.html │ ├── tables.html │ ├── transform.html │ ├── vertical-centering.html │ └── zindex.html ├── floating │ └── index.html ├── forms │ └── index.html ├── grids │ └── index.html ├── img │ └── husky.jpg ├── index.html ├── no-bootstrap │ └── index.html ├── other │ └── index.html ├── positioning │ └── index.html ├── pseudoelements │ └── index.html ├── selectors │ └── index.html ├── tables │ └── index.html ├── transform │ └── index.html ├── underscore-min.js ├── vertical-centering │ └── index.html └── zindex │ └── index.html ├── gulpfile.js ├── package-lock.json ├── package.json └── src ├── app.css ├── app.js ├── examples ├── background-image.html ├── baseline.html ├── boxmodel.html ├── centering.html ├── clearing-floats.html ├── columns.html ├── display.html ├── floating.html ├── forms.html ├── grids.html ├── intro.html ├── no-bootstrap.html ├── positioning.html ├── pseudoelements.html ├── selectors.html ├── tables.html ├── transform.html ├── vertical-centering.html └── zindex.html ├── img └── husky.jpg ├── macros └── framed-problem.html ├── pages ├── background-image.html ├── base.html ├── baseline.html ├── boxmodel.html ├── centering.html ├── clearing-floats.html ├── columns.html ├── display.html ├── floating.html ├── forms.html ├── grids.html ├── index.html ├── no-bootstrap.html ├── other.html ├── positioning.html ├── pseudoelements.html ├── selectors.html ├── tables.html ├── transform.html ├── vertical-centering.html └── zindex.html └── underscore-min.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { 4 | "targets": { 5 | "browsers": [ 6 | "last 2 versions", 7 | "safari >= 7", 8 | "ie > 10", 9 | ] 10 | }, 11 | "debug": false, 12 | "modules": false 13 | }] 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .sass-cache 2 | node_modules/ 3 | -------------------------------------------------------------------------------- /.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whatisjasongoldstein/buildcss/a101fc07807e6918efed4fdd55a07d1c70dab023/.nojekyll -------------------------------------------------------------------------------- /README.html: -------------------------------------------------------------------------------- 1 | # Build Shit in CSS 2 | 3 | A series of examples illustrating some of the less intuitive things in CSS and how to use them. 4 | 5 | 6 | 7 | Think I'm missing something? Examples are easy to write: just make an html and a markdown file with the same name, and open a pull request. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Build Shit in CSS 2 | 3 | A series of examples illustrating some of the less intuitive things in CSS and how to use them. 4 | 5 | 6 | 7 | Think I'm missing something? Examples are easy to write: just make an html and a markdown file with the same name, and open a pull request. 8 | -------------------------------------------------------------------------------- /docs/app.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | height: auto; 3 | min-height: 100%; 4 | line-height: 1.5; 5 | } 6 | 7 | body { 8 | font-family: 'Lato', helvetica, sans-serif; 9 | margin: 0; 10 | position: relative; 11 | } 12 | 13 | pre, code { 14 | font-family: 'Inconsolata', monospace; 15 | background: #eee; 16 | } 17 | 18 | pre { 19 | padding: 5px 10px; 20 | max-width: 40rem; 21 | border-radius: 4px; 22 | } 23 | 24 | a, a:visited { 25 | color: navy; 26 | text-decoration: none; 27 | border-bottom: 1px solid rgba(0, 0, 128, 0.33); 28 | } 29 | 30 | blockquote { 31 | margin: 0; 32 | border-left: 1px solid #000; 33 | padding: 0 10px; 34 | font-style: italic; 35 | } 36 | 37 | .sidebar h1 { 38 | font-size: 1rem; 39 | background: black; 40 | text-align: center; 41 | margin: 0; 42 | color: white; 43 | padding: 1rem 0; 44 | line-height: 1; 45 | } 46 | 47 | .iframe-wrapper { 48 | display: block; 49 | width: 600px; 50 | height: 400px; 51 | position: relative; 52 | border: 1px solid black; 53 | box-shadow: 0 4px 16px rgba(0,0,0,.25); 54 | margin: 40px 0 0 0; 55 | } 56 | 57 | .iframe-wrapper > * { 58 | position: absolute; 59 | width: 100%; 60 | height: 100%; 61 | } 62 | 63 | .iframe-wrapper a { 64 | z-index: 50; 65 | } 66 | .iframe-wrapper iframe { 67 | z-index: 10; 68 | border: 0; 69 | } 70 | 71 | .sidebar { 72 | width: 200px; 73 | box-sizing: border-box; 74 | position: fixed; 75 | height: 100%; 76 | left: 0; 77 | top: 0; 78 | margin: 0; 79 | overflow: scroll; 80 | border-right: 1px solid #f5f5f5; 81 | padding: 0; 82 | list-style-type: none; 83 | } 84 | 85 | .sidebar footer { 86 | font-size: 0.75rem; 87 | margin: 1rem; 88 | } 89 | 90 | .problems { 91 | padding: 0 10px 0 30px; 92 | } 93 | 94 | .problems li { 95 | margin: 10px 0; 96 | } 97 | 98 | .problem { 99 | box-sizing: border-box; 100 | margin: 0 0 0 240px; 101 | padding: 0 0 40px 0; 102 | } 103 | 104 | .problem figcaption { 105 | max-width: 700px; 106 | } 107 | 108 | -------------------------------------------------------------------------------- /docs/app.js: -------------------------------------------------------------------------------- 1 | 2 | _.each(document.querySelectorAll("pre code"), function(el){ 3 | hljs.highlightBlock(el); 4 | }); 5 | -------------------------------------------------------------------------------- /docs/background-image/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Build Shit in CSS 5 | 6 | 7 | 8 | 9 | 10 | 11 | 38 | 39 | 40 | 41 |
42 |
43 | 44 | 45 |
46 |
47 |

Background Image

48 |

Take a look at the MDN page for background-image, and use this picture of a Husky: http://whatisjasongoldstein.github.io/buildcss/img/husky.jpg.

49 |

The image is square, but the boxes we're using it as a background on are not. (You can tell this where the orange background-color shows through.)

50 |

Going left to right, do this:

51 |
    52 |
  1. The image should cover the box (hint: background-size: cover) and be positioned so the tops align.
  2. 53 |
  3. The image should be contained entirely within the box and centered horizontally. (background-size:contain).
      54 |
    • Did the image start tiling when there's extra space? Try playing with background-repeat.
    • 55 |
    56 |
  4. 57 |
  5. The image should be 50% of the box's height and centered (hint: look at background-position).
  6. 58 |
  7. Cover the box again, but this time, center the image so you can see the Husky's nose.
  8. 59 |
  9. Tile a stripe of the image (background-repeat), positioned 10px from the top. Make sure never to cut the image, it shouldn't be cut off at the box.
      60 |
    • Try setting background-size to a percentage to make that happen.
    • 61 |
    62 |
  10. 63 |
  11. Use background-size and background-position to zoom in.
  12. 64 |
65 |
66 |

67 | Special Thanks: The giant fluffy creature shown above is Koda. Because we live in a ridiculous world, you can see more pictures of her on Instagram. 68 |

69 | 70 |
71 |
72 | 73 | 74 | 75 | 76 | 77 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /docs/base/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Build Shit in CSS 5 | 6 | 7 | 8 | 9 | 10 | 11 | 38 | 39 | 40 |
41 |
42 | 43 | 44 |
45 |
46 | 47 |
48 |
49 | 50 | 51 | 52 | 53 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /docs/baseline/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Build Shit in CSS 5 | 6 | 7 | 8 | 9 | 10 | 11 | 38 | 39 | 40 | 41 |
42 |
43 | 44 | 45 |
46 |
47 |

The Baseline (Vertical Align, Line Height, etc.)

48 |

In typography, the baseline is a line the letter sit on. If you've never heard this term, 49 | read the Wikipedia entry) 50 | quickly.

51 |

line-height describes the amount of space between the baselines.

52 |

As you probably guessed, the boxes are inline-blocks. Inline elements sit on the baseline, but you can adjust how they set using the vertical-align property. If you were to look this up on MDN, you'll have the default is baseline, but you can make it hang in the middle or the top accordingly.

53 |

Notes

54 |
    55 |
  • Always set line-height to a number without units, this way it becomes a multiple 56 | of whatever the font-size is. This way, line-height: 2; is like double spacing, 57 | and if the font-size changes, your typography holds together.
  • 58 |
  • Since vertical-align describes the relationship between things to the baseline, its 59 | effect will be more pronounced when the baselines are further apart (bigger line-height).
  • 60 |
61 | 62 |
63 |
64 | 65 | 66 | 67 | 68 | 69 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /docs/boxmodel/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Build Shit in CSS 5 | 6 | 7 | 8 | 9 | 10 | 11 | 38 | 39 | 40 | 41 |
42 |
43 | 44 | 45 |
46 |
47 |

Box Model

48 |

MDN has a pretty good intro to the box model.

49 |

This one should be self explanatory.

50 |

Notes

51 |
    52 |
  • Read about box-sizing, a CSS property that determines, well, exactly what you need.
  • 53 |
  • Notice that the margins "collapse" - when the box with margin: 40px is next to a box with margin: 20px, the two boxes render 20 pixels apart. This is because margins don't add together - they dictate the minimum space 54 | the element needs to be spaced from other stuff. MDN has more on this.
  • 55 |
56 | 57 |
58 |
59 | 60 | 61 | 62 | 63 | 64 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /docs/centering/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Build Shit in CSS 5 | 6 | 7 | 8 | 9 | 10 | 11 | 38 | 39 | 40 | 41 |
42 |
43 | 44 | 45 |
46 |
47 |

Centering

48 |

Inline and inline-block elements are centered by setting the text-align of the parent element to center.

49 |

Block elements are centered by having the left and right margins set to auto (e.g., margin: 0 auto);

50 | 51 |
52 |
53 | 54 | 55 | 56 | 57 | 58 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /docs/clearing-floats/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Build Shit in CSS 5 | 6 | 7 | 8 | 9 | 10 | 11 | 38 | 39 | 40 | 41 |
42 |
43 | 44 | 45 |
46 |
47 |

Clearing Floats

48 |

Often you'll want things that are side by side on opposite ends of a container.

49 |

By default, floating elements overhang their container, as you can see in the top example.

50 |

There are two ways to fix this:

51 |
    52 |
  1. Set overflow:hidden; on the container. This clips anything that runs over, but it also 53 | causes the container to extend to fit the floats.
  2. 54 |
  3. Set an :after psuedoelement on the container and have it clear: both.
      55 |
    • This is useful if you want to be able to hang outside the container in another way. 56 | In the third example, the boxes stick out the top.
    • 57 |
    • In all the examples, there's a box-shadow that would be clipped by overflow: hidden;
    • 58 |
    59 |
  4. 60 |
61 |

Notes

62 |
    63 |
  • Use <hr> for the lines between examples.
  • 64 |
  • myelement:after clears a psuedoelemnt. You need to set it's content and display to make it useful. 65 | content is probably blank in this case.
      66 |
    • We'll cover more on psuedo-elements later.
    • 67 |
    68 |
  • 69 |
70 | 71 |
72 |
73 | 74 | 75 | 76 | 77 | 78 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /docs/columns/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Build Shit in CSS 5 | 6 | 7 | 8 | 9 | 10 | 11 | 38 | 39 | 40 | 41 |
42 |
43 | 44 | 45 |
46 |
47 |

Columns

48 |

Columns are tricky. Try to build this.

49 |

Notes

50 |
    51 |
  • The header is easy, that's just spanning the full width of the page.
  • 52 |
  • The two columns float next to each other at 50% width.
      53 |
    • I'd like to give them some breathing space, so I set each to have some padding 54 | the inside. To make this be counted towards the 50% instead of add to it (which would 55 | make the elements over 50% each and not fit on the line), set box-sizing:border-box.
    • 56 |
    57 |
  • 58 |
  • To make the footer clear floats, it needs to be a block element with clear:both.
      59 |
    • But by default, no matter how much margin-top you put on the footer, it won't create 60 | a gap between the footer and the columns.
        61 |
      • This is because floats are broken out of from the regular layout, so they only respect margins from other floats.
      • 62 |
      • The exception is margins coming from above. You can push a float down with a margin, but margins coming from the side or bottom will have no effect.
      • 63 |
      64 |
    • 65 |
    • There are two ways to fix this:
        66 |
      • Setting margin bottom on the columns.
      • 67 |
      • We can fix this by putting a wrapping div around both elements, which can clear the floats 68 | using either overflow:hidden or an after clearfix, e.g., .wrapper:after {content: ""; display:block; clear:both;}.
      • 69 |
      70 |
    • 71 |
    72 |
  • 73 |
74 |

The "Wrong" Answer

75 |

You could put a <div style="clear:both"></div> between the footer and the columns. It would clear the floats and provide something that the footer's top margin could push against. But then you'd have an empty, unsemantic element that you don't need in your code.

76 |

The very thought of this should fill you with disgust, that such ugliness should be allowed to blight your code even though your users would never notice.

77 |

Aside

78 |

columns: 2; is a thing in CSS3, however, it still doesn't feel ready for prime time. Read more on MDN.

79 | 80 |
81 |
82 | 83 | 84 | 85 | 86 | 87 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /docs/display/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Build Shit in CSS 5 | 6 | 7 | 8 | 9 | 10 | 11 | 38 | 39 | 40 | 41 |
42 |
43 | 44 | 45 |
46 |
47 |

Display

48 |

This is about the Display property.

49 |

You should make it entirely with divs or spans, and use CSS 50 | properties to control them.

51 |

Notes:

52 |
    53 |
  • Inline elements are text, like <b> and <a>. They sit on the same line and can be thought of in things in text. They can have left/right margins but not top or bottom, can't have a set width height, and can't float. I like to think of them as "layout-less".
  • 54 |
  • Block elements like <div> and <p> fill the whole line by default, and stack on top of each other. They have margins, padding, and floats.
  • 55 |
  • Inline-blocks have margins and padding like blocks do, but sit on the same line like inline elements.
  • 56 |
57 |

You'll use all three to build the above.

58 |

Good luck!

59 | 60 |
61 |
62 | 63 | 64 | 65 | 66 | 67 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /docs/examples/background-image.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Background Image 5 | 6 | 54 | 55 | 56 | 57 |
58 |
59 |
60 | 61 |
62 |
63 |
64 | 65 | 66 | -------------------------------------------------------------------------------- /docs/examples/baseline.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The Baseline 5 | 37 | 38 | 39 | 40 |

Spread Out

41 |

Enim in nostrud ea pariatur consequat occaecat tempor consectetur adipisicing est tempor est qui esse minim do do amet ea exercitation proident consequat sint quis cupidatat id et labore culpa cillum eiusmod nulla nostrud esse officia do deserunt id ipsum magna Lorem ad commodo culpa eiusmod laborum do eu nulla.

42 | 43 | 44 |

Tight

45 |

Enim in nostrud ea pariatur consequat occaecat tempor consectetur adipisicing est tempor est qui esse minim do do amet ea exercitation proident consequat sint quis cupidatat id et labore culpa cillum eiusmod nulla nostrud esse officia do deserunt id ipsum magna Lorem ad commodo culpa eiusmod laborum do eu nulla.

46 | 47 | 48 | -------------------------------------------------------------------------------- /docs/examples/boxmodel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Box Model 5 | 6 | 28 | 29 | 30 |
31 | This box is 300px wide, plus border and padding. 32 |
33 | 34 |
35 | This box is 300px wide, including-border and padding. 36 |
37 | 38 |
39 | This box is also 300px wide, with twice as much margin. 40 |
41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /docs/examples/centering.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Centering 5 | 41 | 42 | 43 | 44 |
45 | Center this inline 46 |
47 | 48 |
49 |
Center this block
50 |
51 | 52 |
53 | Center this inline-block, which is 200px wide. 54 |
55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /docs/examples/clearing-floats.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Clearing floats 5 | 49 | 50 | 51 | 52 |
53 |
54 |
55 |
56 | 57 |
58 | 59 |
60 |
61 |
62 |
63 | 64 |
65 | 66 |
67 |
68 |
69 |
70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /docs/examples/columns.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Columns 5 | 38 | 39 | 40 | 41 |
The head goes above both columns.
42 | 43 |
44 |
45 | in est quis aute dolore anim amet irure pariatur nulla quis occaecat eu cupidatat sunt elit anim in pariatur non ullamco ullamco aliqua anim in officia mollit consectetur consequat sit nostrud consequat elit ex mollit pariatur adipisicing aliquip minim ullamco laboris dolore ea deserunt ipsum sint sunt ullamco excepteur proident 46 |
47 |
48 | in irure qui irure amet dolor dolore id officia et proident consectetur labore sint est cupidatat ex ex consectetur occaecat laborum commodo laborum adipisicing cupidatat commodo ipsum in ex laborum enim fugiat aliquip aute laboris qui Lorem voluptate id laboris cillum Lorem ullamco est veniam cillum eiusmod dolor adipisicing fugiat 49 |
50 |
51 | 52 |
53 | This is the footer. It should clear both columns. 54 |
55 | 56 | 57 | -------------------------------------------------------------------------------- /docs/examples/display.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Display stuff 5 | 28 | 29 | 30 | 31 | A poem for mornings: 32 | Coffee, coffee, coffee 33 | Coffee 34 | Coffee, coffee 35 | Everyone shut up 36 | Coffee 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /docs/examples/floating.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Floating and Clearing 5 | 6 | 33 | 34 | 35 | 36 |
1
37 |
2
38 |
3
39 |
4
40 |
5
41 |
6
42 |
7
43 |
8
44 |
9
45 |
10
46 |
11
47 |
12
48 |
13
49 |
14
50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /docs/examples/forms.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Forms 5 | 51 | 52 | 53 | 54 |
55 |

56 | 57 | 58 |

59 | 60 |

61 | 62 | 68 |

69 | 70 |

71 | 72 | 73 |

74 | 75 |

76 | 77 | 78 |

79 | 80 |

81 | 82 |

83 |
84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /docs/examples/grids.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Grids 5 | 6 | 65 | 66 | 67 | 68 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /docs/examples/intro.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Introduction 5 | 18 | 19 | 20 | 21 |

This text is red.

22 |

This text is blue.

23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /docs/examples/no-bootstrap.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | No Bootstrap 5 | 79 | 80 | 81 | 82 | 83 |

84 | 85 | 86 | 87 | 88 | 89 | 90 |

91 |

92 | 93 |

94 | 95 | 96 |

Yay! Something worked the way it was supposed to!

97 | 98 | 99 | -------------------------------------------------------------------------------- /docs/examples/other.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The end! 5 | 24 | 25 | 26 | 27 |

There's always more shit to learn!

28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /docs/examples/positioning.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Positioning 5 | 49 | 50 | 51 | 52 |
Sticky Header!
53 | 54 |
55 | 1 56 | 2 57 | 3 58 | 4 59 | Coffee? 60 |
61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /docs/examples/pseudoelements.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Psuedoelements 5 | 19 | 20 | 21 | 22 | 23 |

Read the fine print.

24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /docs/examples/selectors.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Selectors 5 | 28 | 29 | 30 | 31 |

Headline

32 |

Subhead, next to headline

33 | 34 |

Subhead elsewhere

35 | 36 | 42 | 43 |

Subhead elsewhere

44 |

This subhead doesn't have a border under it.

45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /docs/examples/tables.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Tables 5 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
NameContent
Part 1Adipisicing in magna ipsum ullamco irure et sunt ex deserunt
Part 2Velit amet exercitation aute deserunt do anim consectetur aliqua nulla
Part 1Adipisicing in magna ipsum ullamco irure et sunt ex deserunt
Part 2Velit amet exercitation aute deserunt do anim consectetur aliqua nulla
60 | 61 | 62 | -------------------------------------------------------------------------------- /docs/examples/transform.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Transform 5 | 28 | 29 | 30 | 31 |

Classified

32 | 33 | 34 | -------------------------------------------------------------------------------- /docs/examples/vertical-centering.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Centering and radius 5 | 31 | 32 | 33 | 34 |
35 |
Coffee?
36 |
37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /docs/examples/zindex.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Z-index 5 | 37 | 38 | 39 | 40 |
41 |
42 |
43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /docs/floating/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Build Shit in CSS 5 | 6 | 7 | 8 | 9 | 10 | 11 | 38 | 39 | 40 | 41 |
42 |
43 | 44 | 45 |
46 |
47 |

Floating and clearing

48 |

This isn't a Tetris board. Well, maybe it is. But it's also a demo 49 | of how floats and clears behave.

50 |

Notes

51 |
    52 |
  • Use text-shadow to help the numbers stand out against their backgrounds.
  • 53 |
  • Try making the line-height of the boxes the same as their height. You know how line-heights affect text in paragraphs, but its useful to think of them in relationship to other elements.
  • 54 |
  • The order of the boxes in important. If two boxes float right, the first one will be further right.
  • 55 |
56 | 57 |
58 |
59 | 60 | 61 | 62 | 63 | 64 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /docs/forms/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Build Shit in CSS 5 | 6 | 7 | 8 | 9 | 10 | 11 | 38 | 39 | 40 | 41 |
42 |
43 | 44 | 45 |
46 |
47 |

Forms

48 |

Styling forms is tricky but important. In a large project, 49 | you'll want to create some styles that you can reuse on all your forms 50 | so you don't have to style them indiviually.

51 |

This form markup is similar to what a web framework - say, Django - would generate.

52 |
<form action="." method="POST">    
 53 |     <p>
 54 |         <label>Name</label>
 55 |         <input type="text">
 56 |     </p>
 57 | 
 58 |     <p class="required">
 59 |         <label>Preferred Taco</label>
 60 |         <select>
 61 |             <option>Carne</option>
 62 |             <option>Al Pastor</option>
 63 |             <option>Don't care, just add guac</option>
 64 |             <option>All of Them</option>
 65 |         </select>
 66 |     </p>
 67 | 
 68 |     <p>
 69 |         <label>Spicy?</label>
 70 |         <input type="checkbox">
 71 |     </p>
 72 | 
 73 |     <p>
 74 |         <label>Address</label>
 75 |         <textarea></textarea>
 76 |     </p>
 77 | 
 78 |     <p>
 79 |         <input type="submit" value="Send Tacos!">   
 80 |     </p>
 81 | </form>
 82 | 

Hints

83 |
    84 |
  • Use :before to make the astericks on required fields.
  • 85 |
  • Remember vertical-align when you can't figure out how to make textarea hang down.
  • 86 |
  • Setting the width on label is a good way to make everything line up.
  • 87 |
88 | 89 |
90 |
91 | 92 | 93 | 94 | 95 | 96 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /docs/grids/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Build Shit in CSS 5 | 6 | 7 | 8 | 9 | 10 | 11 | 38 | 39 | 40 | 41 |
42 |
43 | 44 | 45 |
46 |
47 |

Bear Awareness (in Grid Form)

48 |

A common way to lay out a list of visual things is a grid like above.

49 |

This one may be difficult. Especially since you have to use this markup:

50 |
<ul class="images">
 51 |     <li>
 52 |         <figure>
 53 |             <a href="#">
 54 |                 <img src="https://placebear.com/300/200">
 55 |                 <figcaption>Be Aware of the Bear</figcaption>
 56 |             </a>
 57 |         </figure>        
 58 |     </li>
 59 |     <li>
 60 |         <figure>
 61 |             <a href="#">
 62 |                 <img src="https://placebear.com/300/201">
 63 |                 <figcaption>Smokey</figcaption>
 64 |             </a>
 65 |         </figure>  
 66 |     </li>
 67 | 
 68 |     <li>
 69 |         <figure>
 70 |             <a href="#">
 71 |                 <img src="https://placebear.com/300/202">
 72 |                 <figcaption>Gone Fishin</figcaption>
 73 |             </a>
 74 |         </figure>  
 75 |     </li>
 76 | 
 77 |     <li>
 78 |         <figure>
 79 |             <a href="#">
 80 |                 <img src="https://placebear.com/301/203">
 81 |                 <figcaption>I'm stuck</figcaption>
 82 |             </a>
 83 |         </figure>        
 84 |     </li>
 85 |     <li>
 86 |         <figure>
 87 |             <a href="#">
 88 |                 <img src="https://placebear.com/305/205">
 89 |                 <figcaption>PDA?</figcaption>
 90 |             </a>
 91 |         </figure>  
 92 |     </li>
 93 | 
 94 |     <li>
 95 |         <figure>
 96 |             <a href="#">
 97 |                 <img src="https://placebear.com/301/202">
 98 |                 <figcaption>Hello?</figcaption>
 99 |             </a>
100 |         </figure>  
101 |     </li>
102 | </ul>
103 | 

Notes

104 |
    105 |
  • By default, img is an inline element, and will get a mysterious space around it 106 | when when margin is set to zero. This is because inline elements get space around them 107 | from the line-height. You'll want to set your .figure img to display: block so it fills 108 | the space and doesn't have weird layout effects.
  • 109 |
  • Because I like to make things hard, the container has a very thing gray line around it. This means 110 | you have to use margins to create space between items, but not pressing the container. But.. how?
      111 |
    • There are many ways to do this. I take this approach:
        112 |
      1. The items in the list are in charge of layout. If there was no space between them, they'd 113 | be 33.3333% wide with a float: left. But I want to use 1% of that space for margin on each item.
          114 |
        • Since there's only space between the first/middle and last/middle item in each row, 115 | I subtract 2% from the whole, and each item is 32.6666% wide.
            116 |
          • Don't worry about these ridiculous percentages. The browser will usually take care of it. Usually.
          • 117 |
          118 |
        • 119 |
        120 |
      2. 121 |
      3. Set this 1% to margin-left only. Now you don't have to worry about the items at the end of the line - they'll set neatly against the edge.
          122 |
        • This is okay because combined margins doesn't add them together.
        • 123 |
        124 |
      4. 125 |
      5. However, we need to ensure the first item in a line doesn't have a leading margin. For that, I style .images li:nth-child(3n+1) to clear: left and margin-left: 0.
          126 |
        • nth-child is a psuedoclass that can select even, odd, third, etc, of the matching elements. This is useful for striping tables, or clearing the margin of every third+1 element. Read about it on MDN.
        • 127 |
        • Why does it match the first row? Because if n is 0, 3n+1 is 1, or the first element.
        • 128 |
        129 |
      6. 130 |
      131 |
    • 132 |
    133 |
  • 134 |
  • The figcaption is on top of the image. Perhaps position: absolute is a useful tool for this.
  • 135 |
  • The figcaption is also transparent. You can do that with rgba colors. If you've never seen this before, you should look it up on MDN).
      136 |
    • You may be sensing a pattern here. When in doubt, use MDN.
    • 137 |
    138 |
  • 139 |
140 |

The images are from placebear.com. It's exactly what it sounds like it is. 141 | There's also placekitten.com, if you want to make "I can haz placeholder art" jokes.

142 |

For Bonus Points

143 |

Right now, if there were a 7th image, it would hang on the left. 144 | What if you wanted it centered?

145 |

Perhaps, rather than floating, you could make a layout like this where the li's are 146 | inline-blocks, and set text-align:center; on the parent, so if there's 3 the fill the row, 147 | but if there's 1 or 2 they're centered across the row.

148 |

I bet that would work 😉

149 | 150 |
151 |
152 | 153 | 154 | 155 | 156 | 157 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /docs/img/husky.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whatisjasongoldstein/buildcss/a101fc07807e6918efed4fdd55a07d1c70dab023/docs/img/husky.jpg -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Build Shit in CSS 5 | 6 | 7 | 8 | 9 | 10 | 11 | 38 | 39 | 40 | 41 |
42 |
43 | 44 | 45 |
46 |
47 |

An intro to building shit

48 |

This is not a tutorial; it's a series of examples.

49 |

CSS is full of counterintuitive things. For example, float 50 | throws off a lot of people. According to MDN, the definition is:

51 |
52 |

The float CSS property specifies that an element should be taken from the normal flow and placed along the left or right side of its container, where text and inline elements will wrap around it.

53 |
54 |

But this doesn't help you use it to build layouts.

55 |

This series is for you if

56 |
    57 |
  1. You know the syntax - you can write CSS, but have trouble figuring out how to build complex things in it.
  2. 58 |
  3. You understand specificity. If not, do that first. You don't understand CSS if you don't understand specificity.
  4. 59 |
60 |

Format

61 |

Each problem is an example of something made with html in CSS. Your job is to recreate it, without looking at the code. Some hints may be provided. The goal, of course, isn't to build stupid little UI things, but to understand how they can be built by illustrating one or two concepts per example.

62 |

Clicking the image above opens the finished html document. You should view source, read it, open it in the inspector, and fiddle with it until you understand what's happening and why. This case is easy - you need two <p>'s and something like

63 |
.a {color: red;}
64 | .b {color: blue;}
65 | 

Need a place to write code? You should get used to working with plain html files on your desktop. 66 | But you can also work in CodePen or JSFiddle.

67 | 68 |
69 |
70 | 71 | 72 | 73 | 74 | 75 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /docs/no-bootstrap/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Build Shit in CSS 5 | 6 | 7 | 8 | 9 | 10 | 11 | 38 | 39 | 40 | 41 |
42 |
43 | 44 | 45 |
46 |
47 |

Say No to Bootstrap (Sometimes)

48 |

Above, you see several CSS components from Bootstrap, the popular (and highly opinionated) 49 | front-end framework.

50 |

I bet you can build them on your own.

51 |

I bet you don't need Bootstrap at all.

52 |

Why?

53 |

Some Bootstrap users borrow pieces of it because the tooltip is nice and ready to go. Great.

54 |

But others use it as a crutch because they're soft on the front-end. But you're not. 55 | This is a piece of cake compared to our last exercise.

56 |

You can evaluate front-end tools and take the pieces you need, 57 | leave behind what you don't, and not be trapped doing things their way because 58 | you don't know how to draw a button.

59 |

Buttons are easy.

60 |

For Extra Points

61 |

I didn't do any hover effects. You could if you want to show off.

62 |

Now tell us, what do you really think?

63 |

I use Bootstrap's tooltip in production because it's nice and it works. I may even borrow 64 | a few idea from their form code some day - they're good at forms.

65 |

Their responsive stuff, however, is a tragic mess.

66 |

But you're a professional developer. You shouldn't listen to me. You've got an Inspect Element 67 | and a Github, you can read the code of any front-end library and evaluate it for your purposes.

68 | 69 |
70 |
71 | 72 | 73 | 74 | 75 | 76 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /docs/other/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Build Shit in CSS 5 | 6 | 7 | 8 | 9 | 10 | 11 | 38 | 39 | 40 |
41 |
42 |

I'm done here, but you're just getting started

43 |

The best way to learn how to build shit in CSS 44 | is to go forth and build websites.

45 |

But if you're looking for more resources, here's some good stuff:

46 |
    47 |
  1. Froggy Flexbox. Flexbox is a powerful but counterintuitive layout option that's better than floats for vertical alignment, and spacing elements out evenly. I considered doing a page on that, but these guys already did a great job.
  2. 48 |
  3. CSS Grid Garden is a great into the CSS grids, the next big tool for layout.
  4. 49 |
  5. Ethan Marcotte has written two excellent books on responsive design with A Book Apart: Responsive Web Design and Responsive Patterns and Practices. (And really, most of A Book Apart's catalogue is awesome).
  6. 50 |
  7. All About Floats on CSS-Tricks
  8. 51 |
  9. Practical Typgraphy. A short crash course in typography.
      52 |
    • By the way, front end developers should study design. Not only will it help your own apps turn out nicer, it will make it easier to look at a note or comp from a designer, and understand their intent - the problems their trying to solve - instead of just the exact dimensions and colors.
    • 53 |
    54 |
  10. 55 |
56 |

Help make this better

57 |

Did I miss a topic? Is there a resource I should add to the list above? Open an Issue 58 | on Github.

59 |

Contribution Guidelines

60 |

I'd love to see pull requests from other people! Here's what will get accepted:

61 |
    62 |
  • Stick to the format. One page per problem. Each problem should be a minimal example that demonstrates how to use a particular feature of CSS or tackle a particular challenge.
  • 63 |
  • Be clear. Be brief. Be accurate. Avoid jargon—don't assume the reader knows common programming terms yet.
  • 64 |
65 | 66 |
67 |
68 | 69 | 70 | 71 | 72 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /docs/positioning/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Build Shit in CSS 5 | 6 | 7 | 8 | 9 | 10 | 11 | 38 | 39 | 40 | 41 |
42 |
43 | 44 | 45 |
46 |
47 |

Positions

48 |

Goals:

49 |
    50 |
  1. The gray box should have a number in each corner.
  2. 51 |
  3. It should also have a span that's pushed from the top and left by 50px
  4. 52 |
  5. Make a sticky header
  6. 53 |
54 |

Notes:

55 |
    56 |
  • position: absolute; makes top/left/bottom/right set the exact 57 | number of pixels an element will appear relative to its innermost container that also 58 | has a postiion set.
      59 |
    • So putting an absolutely positioned element inside a relative or absolute positioned 60 | element would work like you expect. But if you don't set the position on the parent 61 | (the default position is static) it would be ignored, and the position will be set based 62 | on the next container up the DOM that does have a position (or the whole page).
    • 63 |
    • This is odd, but useful.
    • 64 |
    • Absolute positioned elements don't take up space in the layout, so they will sometimes 65 | wind up on top of other things.
    • 66 |
    67 |
  • 68 |
  • position: relative moves things around from their default position. This means 69 | position:relative; left: 10px; would slide an element to the left by 10 pixels.
  • 70 |
  • position:fixed makes something sticky, and it will stay put as you scroll.
  • 71 |
72 | 73 |
74 |
75 | 76 | 77 | 78 | 79 | 80 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /docs/pseudoelements/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Build Shit in CSS 5 | 6 | 7 | 8 | 9 | 10 | 11 | 38 | 39 | 40 | 41 |
42 |
43 | 44 | 45 |
46 |
47 |

Pseudoelements

48 |

Pseudoelements are things you add before or after an element that can be styled, 49 | but aren't part of the markup and can't be touched by Javascript. They're useful for 50 | icons and symbols, or adding an extra clearing element.

51 |

Here's how you write them.

52 |
.stuff:before {
53 |     content: "this will be inserted before stuff";
54 |     background: green;
55 | }
56 | 

Typically the content is a character or "", but it could be longer text.

57 |

For this example, use this HTML. Obviously, you can't just add a * and an "x" to your markup. That's cheating.

58 |
<button class="close">Close</button>
59 | <p class="footnote">Read the fine print.</p>
60 | 

Sometimes pseudoelements take some finessing to lay them out correctly relative to the rest of the content. 61 | position, margin, line-height and vertical-align are usually good things to try fiddling with.

62 | 63 |
64 |
65 | 66 | 67 | 68 | 69 | 70 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /docs/selectors/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Build Shit in CSS 5 | 6 | 7 | 8 | 9 | 10 | 11 | 38 | 39 | 40 | 41 |
42 |
43 | 44 | 45 |
46 |
47 |

Advanced Selectors

48 |

I assume you already know how to style stuff by its id, class, or element.

49 |

Goals

50 |
    51 |
  1. Headlines (<h1>) followed by a subhead (<h2>) shouldn't have space between them.
  2. 52 |
  3. Subheads that follow a headline should have a red line (border-bottom) under them.
      53 |
    • Subheads elsewhere should have normal margin and no bottom border
    • 54 |
    55 |
  4. 56 |
  5. Italics <i> inside of h1 or h2 should be blue. But not elsewhere.
  6. 57 |
  7. In the list, even items should have a yellow background.
  8. 58 |
59 |

Notes

60 |
    61 |
  • .a + .b is an adjacent selector. It matches elements with a class b that are right after elements with a class .a.
  • 62 |
  • nth-child is pretty cool. You should read about it.
  • 63 |
64 | 65 |
66 |
67 | 68 | 69 | 70 | 71 | 72 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /docs/tables/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Build Shit in CSS 5 | 6 | 7 | 8 | 9 | 10 | 11 | 38 | 39 | 40 | 41 |
42 |
43 | 44 | 45 |
46 |
47 |

Tables

48 |

Tables are for tabular data, never for layout.

49 |

Visually, they're advantage is they'll automatically fit the cells to the available space.

50 |

Here's the markup. (If you're not familiar with any of the elements, you should look them up on MDN.)

51 |
<table>
52 |     <thead>
53 |         <th>Name</th>
54 |         <th>Content</th>
55 |     </thead>
56 |     <tbody>
57 |         <tr>
58 |             <td>Part 1</td>
59 |             <td>Adipisicing in magna ipsum ullamco irure et sunt ex deserunt</td>
60 |         </tr>
61 |         <tr>
62 |             <td>Part 2</td>
63 |             <td>Velit amet exercitation aute deserunt do anim consectetur aliqua nulla</td>
64 |         </tr>
65 |         <tr>
66 |             <td>Part 1</td>
67 |             <td>Adipisicing in magna ipsum ullamco irure et sunt ex deserunt</td>
68 |         </tr>
69 |         <tr>
70 |             <td>Part 2</td>
71 |             <td>Velit amet exercitation aute deserunt do anim consectetur aliqua nulla</td>
72 |         </tr>
73 |     </tbody>
74 | </table>
75 | 

Notes

76 |
    77 |
  • Setting table {border-collapse: collapse;} removes the spacing between cells so you can control it with padding.
  • 78 |
  • Your knowledge of vertical-align and nth-child might be helpful on this one.
  • 79 |
80 | 81 |
82 |
83 | 84 | 85 | 86 | 87 | 88 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /docs/transform/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Build Shit in CSS 5 | 6 | 7 | 8 | 9 | 10 | 11 | 38 | 39 | 40 | 41 |
42 |
43 | 44 | 45 |
46 |
47 |

Transforms

48 |

Transforms are a useful new property in CSS for rotating and warping. 49 | You've already used it to center things vertically. We're going to do one more thing, 50 | since transforms can be strange.

51 |

This is your markup: <h1>Classified</h1>

52 |

Notes

53 |
    54 |
  • You'll need multiple tranform properties. One to rotate, and one to do the vertical centering.
      55 |
    • Putting two transform properties on a CSS block, like having two color properties, causes 56 | one to overwrite the other. Instead, string the values together: translate(-50%, -50%) transform: rotate(90deg) scale(1.5). (Obviously, these aren't the real values.)
    • 57 |
    58 |
  • 59 |
  • Also look up transform-origin. It might help.
  • 60 |
  • Since you're centering something verically, you'll need the container (body) to the width 61 | and height fo the window.
  • 62 |
  • Rotating the element screws up the calculations for subsequent transforms. Do the translate step fo the rotate() first.
  • 63 |
  • Only IE10 and up support transform. When using cutting edge CSS tools, always consider them progress enhancements. Make sure the design works to your satisfaction without them.
  • 64 |
65 | 66 |
67 |
68 | 69 | 70 | 71 | 72 | 73 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /docs/underscore-min.js: -------------------------------------------------------------------------------- 1 | // Underscore.js 1.8.3 2 | // http://underscorejs.org 3 | // (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors 4 | // Underscore may be freely distributed under the MIT license. 5 | (function(){function n(n){function t(t,r,e,u,i,o){for(;i>=0&&o>i;i+=n){var a=u?u[i]:i;e=r(e,t[a],a,t)}return e}return function(r,e,u,i){e=b(e,i,4);var o=!k(r)&&m.keys(r),a=(o||r).length,c=n>0?0:a-1;return arguments.length<3&&(u=r[o?o[c]:c],c+=n),t(r,e,u,o,c,a)}}function t(n){return function(t,r,e){r=x(r,e);for(var u=O(t),i=n>0?0:u-1;i>=0&&u>i;i+=n)if(r(t[i],i,t))return i;return-1}}function r(n,t,r){return function(e,u,i){var o=0,a=O(e);if("number"==typeof i)n>0?o=i>=0?i:Math.max(i+a,o):a=i>=0?Math.min(i+1,a):i+a+1;else if(r&&i&&a)return i=r(e,u),e[i]===u?i:-1;if(u!==u)return i=t(l.call(e,o,a),m.isNaN),i>=0?i+o:-1;for(i=n>0?o:a-1;i>=0&&a>i;i+=n)if(e[i]===u)return i;return-1}}function e(n,t){var r=I.length,e=n.constructor,u=m.isFunction(e)&&e.prototype||a,i="constructor";for(m.has(n,i)&&!m.contains(t,i)&&t.push(i);r--;)i=I[r],i in n&&n[i]!==u[i]&&!m.contains(t,i)&&t.push(i)}var u=this,i=u._,o=Array.prototype,a=Object.prototype,c=Function.prototype,f=o.push,l=o.slice,s=a.toString,p=a.hasOwnProperty,h=Array.isArray,v=Object.keys,g=c.bind,y=Object.create,d=function(){},m=function(n){return n instanceof m?n:this instanceof m?void(this._wrapped=n):new m(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=m),exports._=m):u._=m,m.VERSION="1.8.3";var b=function(n,t,r){if(t===void 0)return n;switch(null==r?3:r){case 1:return function(r){return n.call(t,r)};case 2:return function(r,e){return n.call(t,r,e)};case 3:return function(r,e,u){return n.call(t,r,e,u)};case 4:return function(r,e,u,i){return n.call(t,r,e,u,i)}}return function(){return n.apply(t,arguments)}},x=function(n,t,r){return null==n?m.identity:m.isFunction(n)?b(n,t,r):m.isObject(n)?m.matcher(n):m.property(n)};m.iteratee=function(n,t){return x(n,t,1/0)};var _=function(n,t){return function(r){var e=arguments.length;if(2>e||null==r)return r;for(var u=1;e>u;u++)for(var i=arguments[u],o=n(i),a=o.length,c=0;a>c;c++){var f=o[c];t&&r[f]!==void 0||(r[f]=i[f])}return r}},j=function(n){if(!m.isObject(n))return{};if(y)return y(n);d.prototype=n;var t=new d;return d.prototype=null,t},w=function(n){return function(t){return null==t?void 0:t[n]}},A=Math.pow(2,53)-1,O=w("length"),k=function(n){var t=O(n);return"number"==typeof t&&t>=0&&A>=t};m.each=m.forEach=function(n,t,r){t=b(t,r);var e,u;if(k(n))for(e=0,u=n.length;u>e;e++)t(n[e],e,n);else{var i=m.keys(n);for(e=0,u=i.length;u>e;e++)t(n[i[e]],i[e],n)}return n},m.map=m.collect=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=Array(u),o=0;u>o;o++){var a=e?e[o]:o;i[o]=t(n[a],a,n)}return i},m.reduce=m.foldl=m.inject=n(1),m.reduceRight=m.foldr=n(-1),m.find=m.detect=function(n,t,r){var e;return e=k(n)?m.findIndex(n,t,r):m.findKey(n,t,r),e!==void 0&&e!==-1?n[e]:void 0},m.filter=m.select=function(n,t,r){var e=[];return t=x(t,r),m.each(n,function(n,r,u){t(n,r,u)&&e.push(n)}),e},m.reject=function(n,t,r){return m.filter(n,m.negate(x(t)),r)},m.every=m.all=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=0;u>i;i++){var o=e?e[i]:i;if(!t(n[o],o,n))return!1}return!0},m.some=m.any=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=0;u>i;i++){var o=e?e[i]:i;if(t(n[o],o,n))return!0}return!1},m.contains=m.includes=m.include=function(n,t,r,e){return k(n)||(n=m.values(n)),("number"!=typeof r||e)&&(r=0),m.indexOf(n,t,r)>=0},m.invoke=function(n,t){var r=l.call(arguments,2),e=m.isFunction(t);return m.map(n,function(n){var u=e?t:n[t];return null==u?u:u.apply(n,r)})},m.pluck=function(n,t){return m.map(n,m.property(t))},m.where=function(n,t){return m.filter(n,m.matcher(t))},m.findWhere=function(n,t){return m.find(n,m.matcher(t))},m.max=function(n,t,r){var e,u,i=-1/0,o=-1/0;if(null==t&&null!=n){n=k(n)?n:m.values(n);for(var a=0,c=n.length;c>a;a++)e=n[a],e>i&&(i=e)}else t=x(t,r),m.each(n,function(n,r,e){u=t(n,r,e),(u>o||u===-1/0&&i===-1/0)&&(i=n,o=u)});return i},m.min=function(n,t,r){var e,u,i=1/0,o=1/0;if(null==t&&null!=n){n=k(n)?n:m.values(n);for(var a=0,c=n.length;c>a;a++)e=n[a],i>e&&(i=e)}else t=x(t,r),m.each(n,function(n,r,e){u=t(n,r,e),(o>u||1/0===u&&1/0===i)&&(i=n,o=u)});return i},m.shuffle=function(n){for(var t,r=k(n)?n:m.values(n),e=r.length,u=Array(e),i=0;e>i;i++)t=m.random(0,i),t!==i&&(u[i]=u[t]),u[t]=r[i];return u},m.sample=function(n,t,r){return null==t||r?(k(n)||(n=m.values(n)),n[m.random(n.length-1)]):m.shuffle(n).slice(0,Math.max(0,t))},m.sortBy=function(n,t,r){return t=x(t,r),m.pluck(m.map(n,function(n,r,e){return{value:n,index:r,criteria:t(n,r,e)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.index-t.index}),"value")};var F=function(n){return function(t,r,e){var u={};return r=x(r,e),m.each(t,function(e,i){var o=r(e,i,t);n(u,e,o)}),u}};m.groupBy=F(function(n,t,r){m.has(n,r)?n[r].push(t):n[r]=[t]}),m.indexBy=F(function(n,t,r){n[r]=t}),m.countBy=F(function(n,t,r){m.has(n,r)?n[r]++:n[r]=1}),m.toArray=function(n){return n?m.isArray(n)?l.call(n):k(n)?m.map(n,m.identity):m.values(n):[]},m.size=function(n){return null==n?0:k(n)?n.length:m.keys(n).length},m.partition=function(n,t,r){t=x(t,r);var e=[],u=[];return m.each(n,function(n,r,i){(t(n,r,i)?e:u).push(n)}),[e,u]},m.first=m.head=m.take=function(n,t,r){return null==n?void 0:null==t||r?n[0]:m.initial(n,n.length-t)},m.initial=function(n,t,r){return l.call(n,0,Math.max(0,n.length-(null==t||r?1:t)))},m.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:m.rest(n,Math.max(0,n.length-t))},m.rest=m.tail=m.drop=function(n,t,r){return l.call(n,null==t||r?1:t)},m.compact=function(n){return m.filter(n,m.identity)};var S=function(n,t,r,e){for(var u=[],i=0,o=e||0,a=O(n);a>o;o++){var c=n[o];if(k(c)&&(m.isArray(c)||m.isArguments(c))){t||(c=S(c,t,r));var f=0,l=c.length;for(u.length+=l;l>f;)u[i++]=c[f++]}else r||(u[i++]=c)}return u};m.flatten=function(n,t){return S(n,t,!1)},m.without=function(n){return m.difference(n,l.call(arguments,1))},m.uniq=m.unique=function(n,t,r,e){m.isBoolean(t)||(e=r,r=t,t=!1),null!=r&&(r=x(r,e));for(var u=[],i=[],o=0,a=O(n);a>o;o++){var c=n[o],f=r?r(c,o,n):c;t?(o&&i===f||u.push(c),i=f):r?m.contains(i,f)||(i.push(f),u.push(c)):m.contains(u,c)||u.push(c)}return u},m.union=function(){return m.uniq(S(arguments,!0,!0))},m.intersection=function(n){for(var t=[],r=arguments.length,e=0,u=O(n);u>e;e++){var i=n[e];if(!m.contains(t,i)){for(var o=1;r>o&&m.contains(arguments[o],i);o++);o===r&&t.push(i)}}return t},m.difference=function(n){var t=S(arguments,!0,!0,1);return m.filter(n,function(n){return!m.contains(t,n)})},m.zip=function(){return m.unzip(arguments)},m.unzip=function(n){for(var t=n&&m.max(n,O).length||0,r=Array(t),e=0;t>e;e++)r[e]=m.pluck(n,e);return r},m.object=function(n,t){for(var r={},e=0,u=O(n);u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},m.findIndex=t(1),m.findLastIndex=t(-1),m.sortedIndex=function(n,t,r,e){r=x(r,e,1);for(var u=r(t),i=0,o=O(n);o>i;){var a=Math.floor((i+o)/2);r(n[a])i;i++,n+=r)u[i]=n;return u};var E=function(n,t,r,e,u){if(!(e instanceof t))return n.apply(r,u);var i=j(n.prototype),o=n.apply(i,u);return m.isObject(o)?o:i};m.bind=function(n,t){if(g&&n.bind===g)return g.apply(n,l.call(arguments,1));if(!m.isFunction(n))throw new TypeError("Bind must be called on a function");var r=l.call(arguments,2),e=function(){return E(n,e,t,this,r.concat(l.call(arguments)))};return e},m.partial=function(n){var t=l.call(arguments,1),r=function(){for(var e=0,u=t.length,i=Array(u),o=0;u>o;o++)i[o]=t[o]===m?arguments[e++]:t[o];for(;e=e)throw new Error("bindAll must be passed function names");for(t=1;e>t;t++)r=arguments[t],n[r]=m.bind(n[r],n);return n},m.memoize=function(n,t){var r=function(e){var u=r.cache,i=""+(t?t.apply(this,arguments):e);return m.has(u,i)||(u[i]=n.apply(this,arguments)),u[i]};return r.cache={},r},m.delay=function(n,t){var r=l.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},m.defer=m.partial(m.delay,m,1),m.throttle=function(n,t,r){var e,u,i,o=null,a=0;r||(r={});var c=function(){a=r.leading===!1?0:m.now(),o=null,i=n.apply(e,u),o||(e=u=null)};return function(){var f=m.now();a||r.leading!==!1||(a=f);var l=t-(f-a);return e=this,u=arguments,0>=l||l>t?(o&&(clearTimeout(o),o=null),a=f,i=n.apply(e,u),o||(e=u=null)):o||r.trailing===!1||(o=setTimeout(c,l)),i}},m.debounce=function(n,t,r){var e,u,i,o,a,c=function(){var f=m.now()-o;t>f&&f>=0?e=setTimeout(c,t-f):(e=null,r||(a=n.apply(i,u),e||(i=u=null)))};return function(){i=this,u=arguments,o=m.now();var f=r&&!e;return e||(e=setTimeout(c,t)),f&&(a=n.apply(i,u),i=u=null),a}},m.wrap=function(n,t){return m.partial(t,n)},m.negate=function(n){return function(){return!n.apply(this,arguments)}},m.compose=function(){var n=arguments,t=n.length-1;return function(){for(var r=t,e=n[t].apply(this,arguments);r--;)e=n[r].call(this,e);return e}},m.after=function(n,t){return function(){return--n<1?t.apply(this,arguments):void 0}},m.before=function(n,t){var r;return function(){return--n>0&&(r=t.apply(this,arguments)),1>=n&&(t=null),r}},m.once=m.partial(m.before,2);var M=!{toString:null}.propertyIsEnumerable("toString"),I=["valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"];m.keys=function(n){if(!m.isObject(n))return[];if(v)return v(n);var t=[];for(var r in n)m.has(n,r)&&t.push(r);return M&&e(n,t),t},m.allKeys=function(n){if(!m.isObject(n))return[];var t=[];for(var r in n)t.push(r);return M&&e(n,t),t},m.values=function(n){for(var t=m.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=n[t[u]];return e},m.mapObject=function(n,t,r){t=x(t,r);for(var e,u=m.keys(n),i=u.length,o={},a=0;i>a;a++)e=u[a],o[e]=t(n[e],e,n);return o},m.pairs=function(n){for(var t=m.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=[t[u],n[t[u]]];return e},m.invert=function(n){for(var t={},r=m.keys(n),e=0,u=r.length;u>e;e++)t[n[r[e]]]=r[e];return t},m.functions=m.methods=function(n){var t=[];for(var r in n)m.isFunction(n[r])&&t.push(r);return t.sort()},m.extend=_(m.allKeys),m.extendOwn=m.assign=_(m.keys),m.findKey=function(n,t,r){t=x(t,r);for(var e,u=m.keys(n),i=0,o=u.length;o>i;i++)if(e=u[i],t(n[e],e,n))return e},m.pick=function(n,t,r){var e,u,i={},o=n;if(null==o)return i;m.isFunction(t)?(u=m.allKeys(o),e=b(t,r)):(u=S(arguments,!1,!1,1),e=function(n,t,r){return t in r},o=Object(o));for(var a=0,c=u.length;c>a;a++){var f=u[a],l=o[f];e(l,f,o)&&(i[f]=l)}return i},m.omit=function(n,t,r){if(m.isFunction(t))t=m.negate(t);else{var e=m.map(S(arguments,!1,!1,1),String);t=function(n,t){return!m.contains(e,t)}}return m.pick(n,t,r)},m.defaults=_(m.allKeys,!0),m.create=function(n,t){var r=j(n);return t&&m.extendOwn(r,t),r},m.clone=function(n){return m.isObject(n)?m.isArray(n)?n.slice():m.extend({},n):n},m.tap=function(n,t){return t(n),n},m.isMatch=function(n,t){var r=m.keys(t),e=r.length;if(null==n)return!e;for(var u=Object(n),i=0;e>i;i++){var o=r[i];if(t[o]!==u[o]||!(o in u))return!1}return!0};var N=function(n,t,r,e){if(n===t)return 0!==n||1/n===1/t;if(null==n||null==t)return n===t;n instanceof m&&(n=n._wrapped),t instanceof m&&(t=t._wrapped);var u=s.call(n);if(u!==s.call(t))return!1;switch(u){case"[object RegExp]":case"[object String]":return""+n==""+t;case"[object Number]":return+n!==+n?+t!==+t:0===+n?1/+n===1/t:+n===+t;case"[object Date]":case"[object Boolean]":return+n===+t}var i="[object Array]"===u;if(!i){if("object"!=typeof n||"object"!=typeof t)return!1;var o=n.constructor,a=t.constructor;if(o!==a&&!(m.isFunction(o)&&o instanceof o&&m.isFunction(a)&&a instanceof a)&&"constructor"in n&&"constructor"in t)return!1}r=r||[],e=e||[];for(var c=r.length;c--;)if(r[c]===n)return e[c]===t;if(r.push(n),e.push(t),i){if(c=n.length,c!==t.length)return!1;for(;c--;)if(!N(n[c],t[c],r,e))return!1}else{var f,l=m.keys(n);if(c=l.length,m.keys(t).length!==c)return!1;for(;c--;)if(f=l[c],!m.has(t,f)||!N(n[f],t[f],r,e))return!1}return r.pop(),e.pop(),!0};m.isEqual=function(n,t){return N(n,t)},m.isEmpty=function(n){return null==n?!0:k(n)&&(m.isArray(n)||m.isString(n)||m.isArguments(n))?0===n.length:0===m.keys(n).length},m.isElement=function(n){return!(!n||1!==n.nodeType)},m.isArray=h||function(n){return"[object Array]"===s.call(n)},m.isObject=function(n){var t=typeof n;return"function"===t||"object"===t&&!!n},m.each(["Arguments","Function","String","Number","Date","RegExp","Error"],function(n){m["is"+n]=function(t){return s.call(t)==="[object "+n+"]"}}),m.isArguments(arguments)||(m.isArguments=function(n){return m.has(n,"callee")}),"function"!=typeof/./&&"object"!=typeof Int8Array&&(m.isFunction=function(n){return"function"==typeof n||!1}),m.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},m.isNaN=function(n){return m.isNumber(n)&&n!==+n},m.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"===s.call(n)},m.isNull=function(n){return null===n},m.isUndefined=function(n){return n===void 0},m.has=function(n,t){return null!=n&&p.call(n,t)},m.noConflict=function(){return u._=i,this},m.identity=function(n){return n},m.constant=function(n){return function(){return n}},m.noop=function(){},m.property=w,m.propertyOf=function(n){return null==n?function(){}:function(t){return n[t]}},m.matcher=m.matches=function(n){return n=m.extendOwn({},n),function(t){return m.isMatch(t,n)}},m.times=function(n,t,r){var e=Array(Math.max(0,n));t=b(t,r,1);for(var u=0;n>u;u++)e[u]=t(u);return e},m.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))},m.now=Date.now||function(){return(new Date).getTime()};var B={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},T=m.invert(B),R=function(n){var t=function(t){return n[t]},r="(?:"+m.keys(n).join("|")+")",e=RegExp(r),u=RegExp(r,"g");return function(n){return n=null==n?"":""+n,e.test(n)?n.replace(u,t):n}};m.escape=R(B),m.unescape=R(T),m.result=function(n,t,r){var e=null==n?void 0:n[t];return e===void 0&&(e=r),m.isFunction(e)?e.call(n):e};var q=0;m.uniqueId=function(n){var t=++q+"";return n?n+t:t},m.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var K=/(.)^/,z={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},D=/\\|'|\r|\n|\u2028|\u2029/g,L=function(n){return"\\"+z[n]};m.template=function(n,t,r){!t&&r&&(t=r),t=m.defaults({},t,m.templateSettings);var e=RegExp([(t.escape||K).source,(t.interpolate||K).source,(t.evaluate||K).source].join("|")+"|$","g"),u=0,i="__p+='";n.replace(e,function(t,r,e,o,a){return i+=n.slice(u,a).replace(D,L),u=a+t.length,r?i+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'":e?i+="'+\n((__t=("+e+"))==null?'':__t)+\n'":o&&(i+="';\n"+o+"\n__p+='"),t}),i+="';\n",t.variable||(i="with(obj||{}){\n"+i+"}\n"),i="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+i+"return __p;\n";try{var o=new Function(t.variable||"obj","_",i)}catch(a){throw a.source=i,a}var c=function(n){return o.call(this,n,m)},f=t.variable||"obj";return c.source="function("+f+"){\n"+i+"}",c},m.chain=function(n){var t=m(n);return t._chain=!0,t};var P=function(n,t){return n._chain?m(t).chain():t};m.mixin=function(n){m.each(m.functions(n),function(t){var r=m[t]=n[t];m.prototype[t]=function(){var n=[this._wrapped];return f.apply(n,arguments),P(this,r.apply(m,n))}})},m.mixin(m),m.each(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=o[n];m.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!==n&&"splice"!==n||0!==r.length||delete r[0],P(this,r)}}),m.each(["concat","join","slice"],function(n){var t=o[n];m.prototype[n]=function(){return P(this,t.apply(this._wrapped,arguments))}}),m.prototype.value=function(){return this._wrapped},m.prototype.valueOf=m.prototype.toJSON=m.prototype.value,m.prototype.toString=function(){return""+this._wrapped},"function"==typeof define&&define.amd&&define("underscore",[],function(){return m})}).call(this); 6 | //# sourceMappingURL=underscore-min.map -------------------------------------------------------------------------------- /docs/vertical-centering/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Build Shit in CSS 5 | 6 | 7 | 8 | 9 | 10 | 11 | 38 | 39 | 40 | 41 |
42 |
43 | 44 | 45 |
46 |
47 |

Vertically Centering Things

48 |

The Second Hardest CSS Problem

49 |

margin:0 auto will center a block horizontally, because auto means equal space on each side. 50 | But margin: auto auto has no extra effect, because the automatic top/bottom margin is 0.

51 |

Why? Is the W3C on drugs? Well, maybe. The bigger issue is CSS was originally designed 52 | for relatively simple documents, and we keep pushing its limits.

53 |

There are a few curve-balls here:

54 |

Vertical Centering Notes

55 |
    56 |
  • Once upon a time, this was pretty much impossible. However, the new property transform gives us a way 57 | to hack around it.
  • 58 |
  • We could use position: absolute; left: 50% to move the left edge on an object halfway across its container. However, this means its left edge is aligned to the center, and we need the center aligned to the center.
      59 |
    • You could compensate for this if you knew the exact width. But in a fluid crazy responsive world, 60 | that's not a very realistic requirement.
    • 61 |
    62 |
  • 63 |
  • transform (read about it on MDN) moves things around relative to themselves, no their container. so transform: translateX(50%) will slide an element over by half its width.
  • 64 |
  • And that's our fix. position:absolute; top: 50%; left: 50%; transform: translate(-50%, -50%) will:
      65 |
    1. Align the top and left edges to the center of the container
    2. 66 |
    3. Slide the element up and to the right by half its width and height respectively, so the centers 67 | are aligned for each axis.
    4. 68 |
    69 |
  • 70 |
71 |

Other Notes:

72 |
    73 |
  1. border-radius might be helpful for making things circles.
  2. 74 |
  3. Note that the letter are spaced out (letter-spacing) and the font is all-caps.
      75 |
    • Never type words in all caps for aesthetics reasons - always used text-transform.
    • 76 |
    • What is text-transform, you ask? As usual, you should check on MDN.
    • 77 |
    78 |
  4. 79 |
80 | 81 |
82 |
83 | 84 | 85 | 86 | 87 | 88 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /docs/zindex/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Build Shit in CSS 5 | 6 | 7 | 8 | 9 | 10 | 11 | 38 | 39 | 40 | 41 |
42 |
43 | 44 | 45 |
46 |
47 |

Z-Index

48 |

z-index is how you control the order of overlapping layers.

49 |

For this example, you need to use the following html:

50 |
<div class="box green"></div>
51 | <div class="box blue"></div>
52 | <div class="box red"></div>
53 | 

By default, these boxes would be stacked with green on the bottom, red on top, and blue in the middle. 54 | We're going to manipulate that.

55 |

Notes:

56 |
    57 |
  • Only elements with a set position (not the default) can have z-index. That's not an issue for this case, 58 | because we need to set a position to get the squares to overlap anyway.
  • 59 |
  • z-index: 10; sets an arbitrary number. Higher ones go on top.
  • 60 |
  • It's a good idea to leave some space between layers so if you need to place things between them in the future, you don't need to alter all the values.
      61 |
    • z-index:1; and z-index:2; is a bad idea.
    • 62 |
    • z-index:10; and index:20; is better.
    • 63 |
    64 |
  • 65 |
66 | 67 |
68 |
69 | 70 | 71 | 72 | 73 | 74 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp'); 2 | const browserSync = require('browser-sync').create(); 3 | 4 | // HTML 5 | const gulpNunjucks = require('gulp-nunjucks'); 6 | const nunjucks = require('nunjucks'); 7 | 8 | const reload = browserSync.reload; 9 | const rename = require("gulp-rename"); 10 | 11 | const dist = 'docs'; 12 | const marked = require('marked'); 13 | 14 | 15 | // const templateEnv = new nunjucks.Environment(); 16 | const templateEnv = new nunjucks.Environment( 17 | new nunjucks.FileSystemLoader('src') 18 | ); 19 | 20 | templateEnv.addFilter('markdown', function(str) { 21 | return new nunjucks.runtime.SafeString(marked(str)); 22 | }); 23 | 24 | // 25 | // Copy html test pages. 26 | // 27 | gulp.task('html', () => { 28 | gulp.src('src/pages/*.html') 29 | .pipe(gulpNunjucks.compile(null, { 30 | env: templateEnv, 31 | })) 32 | .pipe(rename(function (path) { 33 | // Make all urls /foo/ instead of foo.html 34 | if (path.basename !== 'index') { 35 | path.basename = `${ path.basename }/index` 36 | } 37 | })) 38 | .pipe(gulp.dest(dist)) 39 | }); 40 | 41 | // 42 | // Copy html test pages. 43 | // 44 | gulp.task('files', () => { 45 | gulp.src('src/**/*.{js,css,jpg}') 46 | .pipe(gulp.dest(dist)); 47 | }); 48 | 49 | // 50 | // Copy html test pages. 51 | // 52 | gulp.task('examples', () => { 53 | gulp.src('src/examples/*.*') 54 | .pipe(gulp.dest(`${ dist }/examples`)); 55 | }); 56 | 57 | 58 | // 59 | // Dev server 60 | // 61 | gulp.task('serve', ['build'], () => { 62 | browserSync.init({ 63 | notify: true, 64 | port: 9000, 65 | open: false, 66 | reloadOnRestart: true, 67 | startPath: '/buildcss/', 68 | server: { 69 | baseDir: ['docs'], 70 | routes: { 71 | '/buildcss/': 'docs' 72 | } 73 | } 74 | }); 75 | 76 | gulp.watch('src/**/*.*', ['files', reload]); 77 | gulp.watch('src/**/*.html', ['html', 'examples', reload]); 78 | gulp.watch('src/**/*.scss', ['css', reload]); 79 | }); 80 | 81 | gulp.task('default', ['serve']); 82 | 83 | gulp.task('build', ['files', 'examples', 'html']) -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "buildcss", 3 | "version": "2.0.0", 4 | "description": "Build Shit in CSS", 5 | "main": "gulp.babel.js", 6 | "directories": { 7 | "doc": "docs" 8 | }, 9 | "dependencies": {}, 10 | "devDependencies": { 11 | "babel-cli": "^6.26.0", 12 | "babel-preset-env": "^1.6.1", 13 | "browser-sync": "^2.24.4", 14 | "gulp": "^3.9.1", 15 | "gulp-nunjucks": "^3.1.1", 16 | "gulp-rename": "^1.2.2", 17 | "marked": "^0.3.19" 18 | }, 19 | "scripts": { 20 | "test": "echo \"Error: no test specified\" && exit 1" 21 | }, 22 | "repository": { 23 | "type": "git", 24 | "url": "git+https://github.com/whatisjasongoldstein/buildcss.git" 25 | }, 26 | "author": "Jason Goldstein", 27 | "license": "UNLICENSED", 28 | "bugs": { 29 | "url": "https://github.com/whatisjasongoldstein/buildcss/issues" 30 | }, 31 | "homepage": "https://github.com/whatisjasongoldstein/buildcss#readme" 32 | } 33 | -------------------------------------------------------------------------------- /src/app.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | height: auto; 3 | min-height: 100%; 4 | line-height: 1.5; 5 | } 6 | 7 | body { 8 | font-family: 'Lato', helvetica, sans-serif; 9 | margin: 0; 10 | position: relative; 11 | } 12 | 13 | pre, code { 14 | font-family: 'Inconsolata', monospace; 15 | background: #eee; 16 | } 17 | 18 | pre { 19 | padding: 5px 10px; 20 | max-width: 40rem; 21 | border-radius: 4px; 22 | } 23 | 24 | a, a:visited { 25 | color: navy; 26 | text-decoration: none; 27 | border-bottom: 1px solid rgba(0, 0, 128, 0.33); 28 | } 29 | 30 | blockquote { 31 | margin: 0; 32 | border-left: 1px solid #000; 33 | padding: 0 10px; 34 | font-style: italic; 35 | } 36 | 37 | .sidebar h1 { 38 | font-size: 1rem; 39 | background: black; 40 | text-align: center; 41 | margin: 0; 42 | color: white; 43 | padding: 1rem 0; 44 | line-height: 1; 45 | } 46 | 47 | .iframe-wrapper { 48 | display: block; 49 | width: 600px; 50 | height: 400px; 51 | position: relative; 52 | border: 1px solid black; 53 | box-shadow: 0 4px 16px rgba(0,0,0,.25); 54 | margin: 40px 0 0 0; 55 | } 56 | 57 | .iframe-wrapper > * { 58 | position: absolute; 59 | width: 100%; 60 | height: 100%; 61 | } 62 | 63 | .iframe-wrapper a { 64 | z-index: 50; 65 | } 66 | .iframe-wrapper iframe { 67 | z-index: 10; 68 | border: 0; 69 | } 70 | 71 | .sidebar { 72 | width: 200px; 73 | box-sizing: border-box; 74 | position: fixed; 75 | height: 100%; 76 | left: 0; 77 | top: 0; 78 | margin: 0; 79 | overflow: scroll; 80 | border-right: 1px solid #f5f5f5; 81 | padding: 0; 82 | list-style-type: none; 83 | } 84 | 85 | .sidebar footer { 86 | font-size: 0.75rem; 87 | margin: 1rem; 88 | } 89 | 90 | .problems { 91 | padding: 0 10px 0 30px; 92 | } 93 | 94 | .problems li { 95 | margin: 10px 0; 96 | } 97 | 98 | .problem { 99 | box-sizing: border-box; 100 | margin: 0 0 0 240px; 101 | padding: 0 0 40px 0; 102 | } 103 | 104 | .problem figcaption { 105 | max-width: 700px; 106 | } 107 | 108 | -------------------------------------------------------------------------------- /src/app.js: -------------------------------------------------------------------------------- 1 | 2 | _.each(document.querySelectorAll("pre code"), function(el){ 3 | hljs.highlightBlock(el); 4 | }); 5 | -------------------------------------------------------------------------------- /src/examples/background-image.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Background Image 5 | 6 | 54 | 55 | 56 | 57 |
58 |
59 |
60 | 61 |
62 |
63 |
64 | 65 | 66 | -------------------------------------------------------------------------------- /src/examples/baseline.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The Baseline 5 | 37 | 38 | 39 | 40 |

Spread Out

41 |

Enim in nostrud ea pariatur consequat occaecat tempor consectetur adipisicing est tempor est qui esse minim do do amet ea exercitation proident consequat sint quis cupidatat id et labore culpa cillum eiusmod nulla nostrud esse officia do deserunt id ipsum magna Lorem ad commodo culpa eiusmod laborum do eu nulla.

42 | 43 | 44 |

Tight

45 |

Enim in nostrud ea pariatur consequat occaecat tempor consectetur adipisicing est tempor est qui esse minim do do amet ea exercitation proident consequat sint quis cupidatat id et labore culpa cillum eiusmod nulla nostrud esse officia do deserunt id ipsum magna Lorem ad commodo culpa eiusmod laborum do eu nulla.

46 | 47 | 48 | -------------------------------------------------------------------------------- /src/examples/boxmodel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Box Model 5 | 6 | 28 | 29 | 30 |
31 | This box is 300px wide, plus border and padding. 32 |
33 | 34 |
35 | This box is 300px wide, including-border and padding. 36 |
37 | 38 |
39 | This box is also 300px wide, with twice as much margin. 40 |
41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/examples/centering.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Centering 5 | 41 | 42 | 43 | 44 |
45 | Center this inline 46 |
47 | 48 |
49 |
Center this block
50 |
51 | 52 |
53 | Center this inline-block, which is 200px wide. 54 |
55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /src/examples/clearing-floats.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Clearing floats 5 | 49 | 50 | 51 | 52 |
53 |
54 |
55 |
56 | 57 |
58 | 59 |
60 |
61 |
62 |
63 | 64 |
65 | 66 |
67 |
68 |
69 |
70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /src/examples/columns.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Columns 5 | 38 | 39 | 40 | 41 |
The head goes above both columns.
42 | 43 |
44 |
45 | in est quis aute dolore anim amet irure pariatur nulla quis occaecat eu cupidatat sunt elit anim in pariatur non ullamco ullamco aliqua anim in officia mollit consectetur consequat sit nostrud consequat elit ex mollit pariatur adipisicing aliquip minim ullamco laboris dolore ea deserunt ipsum sint sunt ullamco excepteur proident 46 |
47 |
48 | in irure qui irure amet dolor dolore id officia et proident consectetur labore sint est cupidatat ex ex consectetur occaecat laborum commodo laborum adipisicing cupidatat commodo ipsum in ex laborum enim fugiat aliquip aute laboris qui Lorem voluptate id laboris cillum Lorem ullamco est veniam cillum eiusmod dolor adipisicing fugiat 49 |
50 |
51 | 52 |
53 | This is the footer. It should clear both columns. 54 |
55 | 56 | 57 | -------------------------------------------------------------------------------- /src/examples/display.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Display stuff 5 | 28 | 29 | 30 | 31 | A poem for mornings: 32 | Coffee, coffee, coffee 33 | Coffee 34 | Coffee, coffee 35 | Everyone shut up 36 | Coffee 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/examples/floating.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Floating and Clearing 5 | 6 | 33 | 34 | 35 | 36 |
1
37 |
2
38 |
3
39 |
4
40 |
5
41 |
6
42 |
7
43 |
8
44 |
9
45 |
10
46 |
11
47 |
12
48 |
13
49 |
14
50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /src/examples/forms.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Forms 5 | 51 | 52 | 53 | 54 |
55 |

56 | 57 | 58 |

59 | 60 |

61 | 62 | 68 |

69 | 70 |

71 | 72 | 73 |

74 | 75 |

76 | 77 | 78 |

79 | 80 |

81 | 82 |

83 |
84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /src/examples/grids.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Grids 5 | 6 | 65 | 66 | 67 | 68 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /src/examples/intro.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Introduction 5 | 18 | 19 | 20 | 21 |

This text is red.

22 |

This text is blue.

23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/examples/no-bootstrap.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | No Bootstrap 5 | 79 | 80 | 81 | 82 | 83 |

84 | 85 | 86 | 87 | 88 | 89 | 90 |

91 |

92 | 93 |

94 | 95 | 96 |

Yay! Something worked the way it was supposed to!

97 | 98 | 99 | -------------------------------------------------------------------------------- /src/examples/positioning.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Positioning 5 | 49 | 50 | 51 | 52 |
Sticky Header!
53 | 54 |
55 | 1 56 | 2 57 | 3 58 | 4 59 | Coffee? 60 |
61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /src/examples/pseudoelements.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Psuedoelements 5 | 19 | 20 | 21 | 22 | 23 |

Read the fine print.

24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/examples/selectors.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Selectors 5 | 28 | 29 | 30 | 31 |

Headline

32 |

Subhead, next to headline

33 | 34 |

Subhead elsewhere

35 | 36 |
    37 |
  • One
  • 38 |
  • Two
  • 39 |
  • Three
  • 40 |
  • Four
  • 41 |
42 | 43 |

Subhead elsewhere

44 |

This subhead doesn't have a border under it.

45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/examples/tables.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Tables 5 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
NameContent
Part 1Adipisicing in magna ipsum ullamco irure et sunt ex deserunt
Part 2Velit amet exercitation aute deserunt do anim consectetur aliqua nulla
Part 1Adipisicing in magna ipsum ullamco irure et sunt ex deserunt
Part 2Velit amet exercitation aute deserunt do anim consectetur aliqua nulla
60 | 61 | 62 | -------------------------------------------------------------------------------- /src/examples/transform.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Transform 5 | 28 | 29 | 30 | 31 |

Classified

32 | 33 | 34 | -------------------------------------------------------------------------------- /src/examples/vertical-centering.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Centering and radius 5 | 31 | 32 | 33 | 34 |
35 |
Coffee?
36 |
37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/examples/zindex.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Z-index 5 | 37 | 38 | 39 | 40 |
41 |
42 |
43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/img/husky.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whatisjasongoldstein/buildcss/a101fc07807e6918efed4fdd55a07d1c70dab023/src/img/husky.jpg -------------------------------------------------------------------------------- /src/macros/framed-problem.html: -------------------------------------------------------------------------------- 1 | {% macro framed(iframe_src, caption) %} 2 |
3 |
4 | 5 | 6 |
7 |
8 | {{ caption|markdown }} 9 |
10 |
11 | {% endmacro %} -------------------------------------------------------------------------------- /src/pages/background-image.html: -------------------------------------------------------------------------------- 1 | {% extends "pages/base.html" %} 2 | {% from "macros/framed-problem.html" import framed %} 3 | 4 | {% set text %} 5 | # Background Image 6 | 7 | Take a look at the MDN page for [`background-image`](https://developer.mozilla.org/en-US/docs/Web/CSS/background-image), and use this picture of a Husky: [`http://whatisjasongoldstein.github.io/buildcss/img/husky.jpg`](http://whatisjasongoldstein.github.io/buildcss/img/husky.jpg). 8 | 9 | The image is square, but the boxes we're using it as a background on are not. (You can tell this where the orange `background-color` shows through.) 10 | 11 | Going left to right, do this: 12 | 13 | 1. The image should `cover` the box (hint: `background-size: cover`) and be positioned so the tops align. 14 | 2. The image should be contained entirely within the box and centered horizontally. (`background-size:contain`). 15 | * Did the image start tiling when there's extra space? Try playing with `background-repeat`. 16 | 3. The image should be 50% of the box's height and centered (hint: look at `background-position`). 17 | 4. Cover the box again, but this time, center the image so you can see the Husky's nose. 18 | 5. Tile a stripe of the image (`background-repeat`), positioned 10px from the top. Make sure never to cut the image, it shouldn't be cut off at the box. 19 | * Try setting `background-size` to a percentage to make that happen. 20 | 6. Use `background-size` and `background-position` to zoom in. 21 | 22 | ----- 23 | 24 | **Special Thanks:** The giant fluffy creature shown above is Koda. Because we live in a ridiculous world, you can see more pictures of her on [Instagram](https://www.instagram.com/thatkoda/). 25 | 26 | {% endset %} 27 | 28 | {% block content %} 29 | {{ framed("/buildcss/examples/background-image.html", text) }} 30 | {% endblock content %} -------------------------------------------------------------------------------- /src/pages/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Build Shit in CSS 5 | 6 | 7 | 8 | 9 | 10 | 11 | 38 | 39 | {% block content %} 40 |
41 |
42 | 43 | 44 |
45 |
46 | {% block text %}{% endblock text %} 47 |
48 |
49 | {% endblock content %} 50 | 51 | 52 | 53 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /src/pages/baseline.html: -------------------------------------------------------------------------------- 1 | {% extends "pages/base.html" %} 2 | {% from "macros/framed-problem.html" import framed %} 3 | 4 | {% set text %} 5 | 6 | 7 | # The Baseline (Vertical Align, Line Height, etc.) 8 | 9 | In typography, the baseline is a line the letter sit on. If you've never heard this term, 10 | read the [Wikipedia entry](https://en.wikipedia.org/wiki/Baseline_\(typography\)) 11 | quickly. 12 | 13 | `line-height` describes the amount of space between the baselines. 14 | 15 | As you probably guessed, the boxes are `inline-block`s. Inline elements sit on the baseline, but you can adjust how they set using the `vertical-align` property. If you were to look this up on [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/vertical-align), you'll have the default is baseline, but you can make it hang in the middle or the top accordingly. 16 | 17 | ### Notes 18 | 19 | * Always set `line-height` to a number without units, this way it becomes a multiple 20 | of whatever the font-size is. This way, `line-height: 2;` is like double spacing, 21 | and if the font-size changes, your typography holds together. 22 | * Since `vertical-align` describes the relationship between things to the baseline, its 23 | effect will be more pronounced when the baselines are further apart (bigger `line-height`). 24 | {% endset %} 25 | 26 | {% block content %} 27 | {{ framed("/buildcss/examples/baseline.html", text) }} 28 | {% endblock content %} 29 | -------------------------------------------------------------------------------- /src/pages/boxmodel.html: -------------------------------------------------------------------------------- 1 | {% extends "pages/base.html" %} 2 | {% from "macros/framed-problem.html" import framed %} 3 | 4 | {% set text %} 5 | # Box Model 6 | 7 | MDN has a pretty good [intro to the box model](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Introduction_to_the_CSS_box_model). 8 | 9 | This one should be self explanatory. 10 | 11 | ## Notes 12 | 13 | * Read about [box-sizing](https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing), a CSS property that determines, well, exactly what you need. 14 | * Notice that the margins "collapse" - when the box with `margin: 40px` is next to a box with `margin: 20px`, the two boxes render 20 pixels apart. This is because **margins don't add together** - they dictate the minimum space 15 | the element needs to be spaced from other stuff. [MDN has more on this](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing). 16 | {% endset %} 17 | 18 | {% block content %} 19 | {{ framed("/buildcss/examples/boxmodel.html", text) }} 20 | {% endblock content %} 21 | -------------------------------------------------------------------------------- /src/pages/centering.html: -------------------------------------------------------------------------------- 1 | {% extends "pages/base.html" %} 2 | {% from "macros/framed-problem.html" import framed %} 3 | 4 | {% set text %} 5 | # Centering 6 | 7 | Inline and inline-block elements are centered by setting the `text-align` of the parent element to center. 8 | 9 | Block elements are centered by having the left and right `margin`s set to `auto` (e.g., `margin: 0 auto`); 10 | {% endset %} 11 | 12 | {% block content %} 13 | {{ framed("/buildcss/examples/centering.html", text) }} 14 | {% endblock content %} 15 | 16 | -------------------------------------------------------------------------------- /src/pages/clearing-floats.html: -------------------------------------------------------------------------------- 1 | {% extends "pages/base.html" %} 2 | {% from "macros/framed-problem.html" import framed %} 3 | 4 | {% set text %} 5 | 6 | # Clearing Floats 7 | 8 | Often you'll want things that are side by side on opposite ends of a container. 9 | 10 | By default, floating elements overhang their container, as you can see in the top example. 11 | 12 | There are two ways to fix this: 13 | 14 | 1. Set `overflow:hidden;` on the container. This clips anything that runs over, but it also 15 | causes the container to extend to fit the floats. 16 | 2. Set an `:after` psuedoelement on the container and have it `clear: both`. 17 | * This is useful if you want to be able to hang outside the container in another way. 18 | In the third example, the boxes stick out the top. 19 | * In all the examples, there's a `box-shadow` that would be clipped by `overflow: hidden;` 20 | 21 | 22 | ## Notes 23 | 24 | * Use `
` for the lines between examples. 25 | * `myelement:after` clears a psuedoelemnt. You need to set it's `content` and `display` to make it useful. 26 | `content` is probably blank in this case. 27 | * We'll cover more on psuedo-elements later. 28 | {% endset %} 29 | 30 | {% block content %} 31 | {{ framed("/buildcss/examples/clearing-floats.html", text) }} 32 | {% endblock content %} 33 | -------------------------------------------------------------------------------- /src/pages/columns.html: -------------------------------------------------------------------------------- 1 | {% extends "pages/base.html" %} 2 | {% from "macros/framed-problem.html" import framed %} 3 | 4 | {% set text %} 5 | # Columns 6 | 7 | Columns are tricky. Try to build this. 8 | 9 | ## Notes 10 | 11 | * The header is easy, that's just spanning the full width of the page. 12 | * The two columns float next to each other at 50% width. 13 | * I'd like to give them some breathing space, so I set each to have some padding 14 | the inside. To make this be counted towards the 50% instead of add to it (which would 15 | make the elements over 50% each and not fit on the line), set `box-sizing:border-box`. 16 | * To make the footer clear floats, it needs to be a block element with `clear:both`. 17 | * But by default, no matter how much `margin-top` you put on the footer, it won't create 18 | a gap between the footer and the columns. 19 | * This is because floats are broken out of from the regular layout, so they **only respect margins from other floats**. 20 | * The exception is margins coming from above. You can push a float down with a margin, but margins coming from the side or bottom will have no effect. 21 | * There are two ways to fix this: 22 | * Setting margin bottom on the columns. 23 | * We can fix this by putting a wrapping div around both elements, which can clear the floats 24 | using either `overflow:hidden` or an after clearfix, e.g., `.wrapper:after {content: ""; display:block; clear:both;}`. 25 | 26 | 27 | ### The "Wrong" Answer 28 | 29 | You *could* put a `
` between the footer and the columns. It would clear the floats and provide something that the footer's top margin could push against. But then you'd have an empty, unsemantic element that you don't need in your code. 30 | 31 | The very thought of this should fill you with disgust, that such ugliness should be allowed to blight your code even though your users would never notice. 32 | 33 | ### Aside 34 | 35 | `columns: 2;` is a thing in CSS3, however, it still doesn't feel ready for prime time. [Read more on MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/columns). 36 | {% endset %} 37 | 38 | {% block content %} 39 | {{ framed("/buildcss/examples/columns.html", text) }} 40 | {% endblock content %} -------------------------------------------------------------------------------- /src/pages/display.html: -------------------------------------------------------------------------------- 1 | {% extends "pages/base.html" %} 2 | {% from "macros/framed-problem.html" import framed %} 3 | 4 | {% set text %} 5 | # Display 6 | 7 | This is about the [Display](https://developer.mozilla.org/en-US/docs/Web/CSS/display) property. 8 | 9 | You should make it entirely with divs or spans, and use CSS 10 | properties to control them. 11 | 12 | 13 | ## Notes: 14 | 15 | * Inline elements are text, like `` and ``. They sit on the same line and can be thought of in things in text. They can have left/right margins but not top or bottom, can't have a set width height, and can't float. I like to think of them as "layout-less". 16 | * Block elements like `
` and `

` fill the whole line by default, and stack on top of each other. They have margins, padding, and floats. 17 | * Inline-blocks have margins and padding like blocks do, but sit on the same line like inline elements. 18 | 19 | You'll use all three to build the above. 20 | 21 | Good luck! 22 | {% endset %} 23 | 24 | {% block content %} 25 | {{ framed("/buildcss/examples/display.html", text) }} 26 | {% endblock content %} -------------------------------------------------------------------------------- /src/pages/floating.html: -------------------------------------------------------------------------------- 1 | {% extends "pages/base.html" %} 2 | {% from "macros/framed-problem.html" import framed %} 3 | 4 | {% set text %} 5 | 6 | # Floating and clearing 7 | 8 | This isn't a Tetris board. Well, maybe it is. But it's also a demo 9 | of how floats and clears behave. 10 | 11 | ## Notes 12 | 13 | * Use [text-shadow](https://developer.mozilla.org/en-US/docs/Web/CSS/text-shadow) to help the numbers stand out against their backgrounds. 14 | * Try making the `line-height` of the boxes the same as their height. You know how `line-heights` affect text in paragraphs, but its useful to think of them in relationship to other elements. 15 | * The order of the boxes in important. If two boxes float right, the first one will be further right. 16 | {% endset %} 17 | 18 | {% block content %} 19 | {{ framed("/buildcss/examples/floating.html", text) }} 20 | {% endblock content %} 21 | -------------------------------------------------------------------------------- /src/pages/forms.html: -------------------------------------------------------------------------------- 1 | {% extends "pages/base.html" %} 2 | {% from "macros/framed-problem.html" import framed %} 3 | 4 | {% set text %} 5 | # Forms 6 | 7 | Styling forms is tricky but important. In a large project, 8 | you'll want to create some styles that you can reuse on all your forms 9 | so you don't have to style them indiviually. 10 | 11 | This form markup is similar to what a web framework - say, Django - would generate. 12 | 13 |

14 |

15 | 16 | 17 |

18 | 19 |

20 | 21 | 27 |

28 | 29 |

30 | 31 | 32 |

33 | 34 |

35 | 36 | 37 |

38 | 39 |

40 | 41 |

42 |
43 | 44 | ### Hints 45 | * Use `:before` to make the astericks on required fields. 46 | * Remember vertical-align when you can't figure out how to make textarea hang down. 47 | * Setting the width on `label` is a good way to make everything line up. 48 | 49 | {% endset %} 50 | 51 | {% block content %} 52 | {{ framed("/buildcss/examples/forms.html", text) }} 53 | {% endblock content %} -------------------------------------------------------------------------------- /src/pages/grids.html: -------------------------------------------------------------------------------- 1 | {% extends "pages/base.html" %} 2 | {% from "macros/framed-problem.html" import framed %} 3 | 4 | {% set text %} 5 | # Bear Awareness (in Grid Form) 6 | 7 | A common way to lay out a list of visual things is a grid like above. 8 | 9 | This one may be difficult. Especially since you have to use this markup: 10 | 11 |
64 | 65 | ### Notes 66 | * By default, `img` is an inline element, and will get a mysterious space around it 67 | when when margin is set to zero. This is because inline elements get space around them 68 | from the `line-height`. You'll want to set your `.figure img` to `display: block` so it fills 69 | the space and doesn't have weird layout effects. 70 | * Because I like to make things hard, the container has a very thing gray line around it. This means 71 | you have to use margins to create space between items, but not pressing the container. But.. how? 72 | * There are many ways to do this. I take this approach: 73 | 1. The items in the list are in charge of layout. If there was no space between them, they'd 74 | be 33.3333% wide with a `float: left`. But I want to use 1% of that space for margin on each item. 75 | * Since there's only space between the first/middle and last/middle item in each row, 76 | I subtract 2% from the whole, and each item is 32.6666% wide. 77 | * Don't worry about these ridiculous percentages. The browser will usually take care of it. Usually. 78 | 2. Set this 1% to `margin-left` only. Now you don't have to worry about the items at the end of the line - they'll set neatly against the edge. 79 | * This is okay because combined margins doesn't add them together. 80 | 3. However, we need to ensure the first item in a line doesn't have a leading margin. For that, I style `.images li:nth-child(3n+1)` to `clear: left` and `margin-left: 0`. 81 | * `nth-child` is a psuedoclass that can select even, odd, third, etc, of the matching elements. This is useful for striping tables, or clearing the margin of every third+1 element. Read about it on [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/%3Anth-child). 82 | * Why does it match the first row? Because if `n` is `0`, 3n+1 is 1, or the first element. 83 | * The `figcaption` is on top of the image. Perhaps `position: absolute` is a useful tool for this. 84 | * The `figcaption` is also transparent. You can do that with `rgba` colors. If you've never seen this before, you should [look it up on MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#rgba()). 85 | * You may be sensing a pattern here. When in doubt, use MDN. 86 | 87 | The images are from [placebear.com](https://placebear.com). It's exactly what it sounds like it is. 88 | There's also [placekitten.com](https://placekitten.com), if you want to make "I can haz placeholder art" jokes. 89 | 90 | ### For Bonus Points 91 | 92 | Right now, if there were a 7th image, it would hang on the left. 93 | What if you wanted it centered? 94 | 95 | Perhaps, rather than floating, you could make a layout like this where the `li`'s are 96 | `inline-block`s, and set `text-align:center;` on the parent, so if there's 3 the fill the row, 97 | but if there's 1 or 2 they're centered across the row. 98 | 99 | I bet that would work 😉 100 | 101 | {% endset %} 102 | 103 | {% block content %} 104 | {{ framed("/buildcss/examples/grids.html", text) }} 105 | {% endblock content %} -------------------------------------------------------------------------------- /src/pages/index.html: -------------------------------------------------------------------------------- 1 | {% extends "pages/base.html" %} 2 | {% from "macros/framed-problem.html" import framed %} 3 | 4 | {% set text %} 5 | # An intro to building shit 6 | 7 | This is not a tutorial; it's a series of examples. 8 | 9 | CSS is full of counterintuitive things. For example, **float** 10 | throws off a lot of people. According to MDN, the definition is: 11 | 12 | > The float CSS property specifies that an element should be taken from the normal flow and placed along the left or right side of its container, where text and inline elements will wrap around it. 13 | 14 | But this doesn't help you use it to build layouts. 15 | 16 | ## This series is for you if 17 | 18 | 1. You know the syntax - you can write CSS, but have trouble figuring out how to build complex things in it. 19 | 2. You understand [specificity](http://sixrevisions.com/css/css-specificity/). If not, do that first. You don't understand CSS if you don't understand specificity. 20 | 21 | ## Format 22 | 23 | Each problem is an example of something made with html in CSS. Your job is to recreate it, without looking at the code. Some hints may be provided. The goal, of course, isn't to build stupid little UI things, but to understand *how* they can be built by illustrating one or two concepts per example. 24 | 25 | **Clicking the image above opens the finished html document.** You should view source, read it, open it in the *inspector*, and fiddle with it until you understand what's happening and why. This case is easy - you need two `

`'s and something like 26 | 27 | ``` 28 | .a {color: red;} 29 | .b {color: blue;} 30 | ``` 31 | 32 | **Need a place to write code?** You should get used to working with plain html files on your desktop. 33 | But you can also work in [CodePen](https://codepen.io) or [JSFiddle](https://jsfiddle.net/). 34 | {% endset %} 35 | 36 | {% block content %} 37 | {{ framed("/buildcss/examples/intro.html", text) }} 38 | {% endblock content %} 39 | -------------------------------------------------------------------------------- /src/pages/no-bootstrap.html: -------------------------------------------------------------------------------- 1 | {% extends "pages/base.html" %} 2 | {% from "macros/framed-problem.html" import framed %} 3 | 4 | {% set text %} 5 | 6 | # Say No to Bootstrap (Sometimes) 7 | 8 | Above, you see several CSS components from [Bootstrap](http://getbootstrap.com/), the popular (and highly opinionated) 9 | front-end framework. 10 | 11 | I bet you can build them on your own. 12 | 13 | I bet you don't need Bootstrap at all. 14 | 15 | ### Why? 16 | 17 | Some Bootstrap users borrow pieces of it because the tooltip is nice and ready to go. Great. 18 | 19 | But others use it as a crutch because they're soft on the front-end. But you're not. 20 | This is a piece of cake compared to our last exercise. 21 | 22 | You can evaluate front-end tools and take the pieces you need, 23 | leave behind what you don't, and not be trapped doing things their way because 24 | you don't know how to draw a button. 25 | 26 | Buttons are easy. 27 | 28 | ### For Extra Points 29 | 30 | I didn't do any hover effects. You could if you want to show off. 31 | 32 | #### Now tell us, what do you really think? 33 | 34 | I use Bootstrap's tooltip in production because it's nice and it works. I may even borrow 35 | a few idea from their form code some day - they're good at forms. 36 | 37 | Their responsive stuff, however, is a tragic mess. 38 | 39 | But you're a professional developer. You shouldn't listen to me. You've got an Inspect Element 40 | and a Github, you can read the code of any front-end library and evaluate it for your purposes. 41 | {% endset %} 42 | 43 | {% block content %} 44 | {{ framed("/buildcss/examples/no-bootstrap.html", text) }} 45 | {% endblock content %} 46 | -------------------------------------------------------------------------------- /src/pages/other.html: -------------------------------------------------------------------------------- 1 | {% extends "pages/base.html" %} 2 | {% block content %} 3 |

4 |
5 | {% filter markdown %} 6 | # I'm done here, but you're just getting started 7 | 8 | The best way to learn how to build shit in CSS 9 | is to go forth and build websites. 10 | 11 | But if you're looking for more resources, here's some good stuff: 12 | 13 | 1. [Froggy Flexbox](http://flexboxfroggy.com/). Flexbox is a powerful but counterintuitive layout option that's better than floats for vertical alignment, and spacing elements out evenly. I considered doing a page on that, but these guys already did a great job. 14 | 3. [CSS Grid Garden](http://cssgridgarden.com/) is a great into the CSS grids, the next big tool for layout. 15 | 4. Ethan Marcotte has written two excellent books on responsive design with A Book Apart: [Responsive Web Design](http://abookapart.com/products/responsive-web-design) and [Responsive Patterns and Practices](http://abookapart.com/products/responsive-design-patterns-principles). (And really, most of A Book Apart's catalogue is awesome). 16 | 5. [All About Floats](https://css-tricks.com/all-about-floats/) on CSS-Tricks 17 | 6. [Practical Typgraphy](http://practicaltypography.com/). A short crash course in typography. 18 | * By the way, front end developers should study design. Not only will it help your own apps turn out nicer, it will make it easier to look at a note or comp from a designer, and understand their intent - the problems their trying to solve - instead of just the exact dimensions and colors. 19 | 20 | ## Help make this better 21 | 22 | Did I miss a topic? Is there a resource I should add to the list above? Open an Issue 23 | on [Github](https://github.com/whatisjasongoldstein/buildcss/issues). 24 | 25 | ## Contribution Guidelines 26 | 27 | I'd love to see pull requests from other people! Here's what will get accepted: 28 | 29 | * Stick to the format. One page per problem. Each problem should be a minimal example that demonstrates how to use a particular feature of CSS or tackle a particular challenge. 30 | * Be clear. Be brief. Be accurate. Avoid jargon—don't assume the reader knows common programming terms yet. 31 | {% endfilter %} 32 |
33 |
34 | {% endblock content %} -------------------------------------------------------------------------------- /src/pages/positioning.html: -------------------------------------------------------------------------------- 1 | {% extends "pages/base.html" %} 2 | {% from "macros/framed-problem.html" import framed %} 3 | 4 | {% set text %} 5 | # Positions 6 | 7 | ## Goals: 8 | 9 | 1. The gray box should have a number in each corner. 10 | 2. It should also have a span that's pushed from the top and left by `50px` 11 | 3. Make a sticky header 12 | 13 | ### Notes: 14 | 15 | * `position: absolute;` makes `top`/`left`/`bottom`/`right` set the exact 16 | number of pixels an element will appear relative to its innermost container that *also* 17 | has a postiion set. 18 | * So putting an absolutely positioned element inside a relative or absolute positioned 19 | element would work like you expect. But if you don't set the position on the parent 20 | (the default position is `static`) it would be ignored, and the position will be set based 21 | on the next container up the DOM that does have a position (or the whole page). 22 | * This is odd, but useful. 23 | * Absolute positioned elements don't take up space in the layout, so they will sometimes 24 | wind up on top of other things. 25 | * `position: relative` moves things around from their default position. This means 26 | `position:relative; left: 10px;` would slide an element to the left by 10 pixels. 27 | * `position:fixed` makes something sticky, and it will stay put as you scroll. 28 | {% endset %} 29 | 30 | {% block content %} 31 | {{ framed("/buildcss/examples/positioning.html", text) }} 32 | {% endblock content %} 33 | -------------------------------------------------------------------------------- /src/pages/pseudoelements.html: -------------------------------------------------------------------------------- 1 | {% extends "pages/base.html" %} 2 | {% from "macros/framed-problem.html" import framed %} 3 | 4 | {% set text %} 5 | # Pseudoelements 6 | 7 | Pseudoelements are things you add before or after an element that can be styled, 8 | but aren't part of the markup and can't be touched by Javascript. They're useful for 9 | icons and symbols, or adding an extra clearing element. 10 | 11 | Here's how you write them. 12 | 13 | .stuff:before { 14 | content: "this will be inserted before stuff"; 15 | background: green; 16 | } 17 | 18 | Typically the content is a character or `""`, but it could be longer text. 19 | 20 | For this example, use this HTML. Obviously, you can't just add a * and an "x" to your markup. That's cheating. 21 | 22 | 23 |

Read the fine print.

24 | 25 | Sometimes pseudoelements take some finessing to lay them out correctly relative to the rest of the content. 26 | `position`, `margin`, `line-height` and `vertical-align` are usually good things to try fiddling with. 27 | {% endset %} 28 | 29 | {% block content %} 30 | {{ framed("/buildcss/examples/pseudoelements.html", text) }} 31 | {% endblock content %} 32 | -------------------------------------------------------------------------------- /src/pages/selectors.html: -------------------------------------------------------------------------------- 1 | {% extends "pages/base.html" %} 2 | {% from "macros/framed-problem.html" import framed %} 3 | 4 | {% set text %} 5 | # Advanced Selectors 6 | 7 | I assume you already know how to style stuff by its `id`, `class`, or `element`. 8 | 9 | ## Goals 10 | 1. Headlines (`

`) followed by a subhead (`

`) shouldn't have space between them. 11 | 2. Subheads that follow a headline should have a red line (`border-bottom`) under them. 12 | * Subheads elsewhere should have normal margin and no bottom border 13 | 3. Italics `` inside of h1 or h2 should be blue. But not elsewhere. 14 | 4. In the list, even items should have a yellow background. 15 | 16 | ## Notes 17 | 18 | * `.a + .b` is an adjacent selector. It matches elements with a class `b` that are right after elements with a class `.a`. 19 | * `nth-child` is pretty cool. You should [read about it](https://developer.mozilla.org/en-US/docs/Web/CSS/%3Anth-child). 20 | {% endset %} 21 | 22 | {% block content %} 23 | {{ framed("/buildcss/examples/selectors.html", text) }} 24 | {% endblock content %} 25 | -------------------------------------------------------------------------------- /src/pages/tables.html: -------------------------------------------------------------------------------- 1 | {% extends "pages/base.html" %} 2 | {% from "macros/framed-problem.html" import framed %} 3 | 4 | {% set text %} 5 | # Tables 6 | 7 | Tables are for tabular data, never for layout. 8 | 9 | Visually, they're advantage is they'll automatically fit the cells to the available space. 10 | 11 | Here's the markup. (If you're not familiar with any of the elements, you should look them up on MDN.) 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
NameContent
Part 1Adipisicing in magna ipsum ullamco irure et sunt ex deserunt
Part 2Velit amet exercitation aute deserunt do anim consectetur aliqua nulla
Part 1Adipisicing in magna ipsum ullamco irure et sunt ex deserunt
Part 2Velit amet exercitation aute deserunt do anim consectetur aliqua nulla
37 | 38 | 39 | ### Notes 40 | * Setting `table {border-collapse: collapse;}` removes the spacing between cells so you can control it with padding. 41 | * Your knowledge of `vertical-align` and `nth-child` might be helpful on this one.{% endset %} 42 | 43 | {% block content %} 44 | {{ framed("/buildcss/examples/tables.html", text) }} 45 | {% endblock content %} 46 | -------------------------------------------------------------------------------- /src/pages/transform.html: -------------------------------------------------------------------------------- 1 | {% extends "pages/base.html" %} 2 | {% from "macros/framed-problem.html" import framed %} 3 | 4 | {% set text %} 5 | 6 | # Transforms 7 | 8 | Transforms are a useful new property in CSS for rotating and warping. 9 | You've already used it to center things vertically. We're going to do one more thing, 10 | since transforms can be strange. 11 | 12 | This is your markup: `

Classified

` 13 | 14 | ## Notes 15 | * You'll need multiple tranform properties. One to rotate, and one to do the vertical centering. 16 | * Putting two transform properties on a CSS block, like having two `color` properties, causes 17 | one to overwrite the other. Instead, string the values together: `translate(-50%, -50%) transform: rotate(90deg) scale(1.5)`. (Obviously, these aren't the real values.) 18 | * Also look up `transform-origin`. It might help. 19 | * Since you're centering something verically, you'll need the container (`body`) to the width 20 | and height fo the window. 21 | * Rotating the element screws up the calculations for subsequent transforms. Do the `translate` step fo the `rotate()` first. 22 | * Only IE10 and up support `transform`. When using cutting edge CSS tools, always consider them progress enhancements. Make sure the design works to your satisfaction without them. 23 | {% endset %} 24 | 25 | {% block content %} 26 | {{ framed("/buildcss/examples/transform.html", text) }} 27 | {% endblock content %} 28 | -------------------------------------------------------------------------------- /src/pages/vertical-centering.html: -------------------------------------------------------------------------------- 1 | {% extends "pages/base.html" %} 2 | {% from "macros/framed-problem.html" import framed %} 3 | 4 | {% set text %} 5 | # Vertically Centering Things 6 | ## The Second Hardest CSS Problem 7 | 8 | `margin:0 auto` will center a block horizontally, because auto means equal space on each side. 9 | But `margin: auto auto` has no extra effect, because the automatic top/bottom margin is 0. 10 | 11 | Why? Is the W3C on drugs? Well, maybe. The bigger issue is CSS was originally designed 12 | for relatively simple documents, and we keep pushing its limits. 13 | 14 | There are a few curve-balls here: 15 | 16 | ## Vertical Centering Notes 17 | * Once upon a time, this was pretty much impossible. However, the new property `transform` gives us a way 18 | to hack around it. 19 | * We could use `position: absolute; left: 50%` to move the left edge on an object halfway across its container. However, this means its left edge is aligned to the center, and we need the center aligned to the center. 20 | * You could compensate for this if you knew the exact width. But in a fluid crazy responsive world, 21 | that's not a very realistic requirement. 22 | * `transform` (read about it on [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/transform)) moves things around relative to themselves, no their container. so `transform: translateX(50%)` will slide an element over by half its width. 23 | * And that's our fix. `position:absolute; top: 50%; left: 50%; transform: translate(-50%, -50%)` will: 24 | 1. Align the top and left edges to the center of the container 25 | 2. Slide the element up and to the right by half its width and height respectively, so the centers 26 | are aligned for each axis. 27 | 28 | ## Other Notes: 29 | 30 | 1. `border-radius` might be helpful for making things circles. 31 | 2. Note that the letter are spaced out (`letter-spacing`) and the font is all-caps. 32 | * Never type words in all caps for aesthetics reasons - always used `text-transform`. 33 | * What is `text-transform`, you ask? As usual, you should check on [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/text-transform). 34 | {% endset %} 35 | 36 | {% block content %} 37 | {{ framed("/buildcss/examples/vertical-centering.html", text) }} 38 | {% endblock content %} 39 | -------------------------------------------------------------------------------- /src/pages/zindex.html: -------------------------------------------------------------------------------- 1 | {% extends "pages/base.html" %} 2 | {% from "macros/framed-problem.html" import framed %} 3 | 4 | {% set text %} 5 | # Z-Index 6 | 7 | `z-index` is how you control the order of overlapping layers. 8 | 9 | For this example, you need to use the following html: 10 | 11 |
12 |
13 |
14 | 15 | By default, these boxes would be stacked with green on the bottom, red on top, and blue in the middle. 16 | We're going to manipulate that. 17 | 18 | 19 | ## Notes: 20 | * Only elements with a set `position` (not the default) can have `z-index`. That's not an issue for this case, 21 | because we need to set a position to get the squares to overlap anyway. 22 | * `z-index: 10;` sets an arbitrary number. Higher ones go on top. 23 | * It's a good idea to leave some space between layers so if you need to place things between them in the future, you don't need to alter all the values. 24 | * `z-index:1;` and `z-index:2`; is a bad idea. 25 | * `z-index:10;` and `index:20;` is better. 26 | {% endset %} 27 | 28 | {% block content %} 29 | {{ framed("/buildcss/examples/zindex.html", text) }} 30 | {% endblock content %} 31 | --------------------------------------------------------------------------------