Slide 1

Slide 1 text

WRITING BETTER HTML & CSS

Slide 2

Slide 2 text

[email protected] @chriscoyier CHRIS COYIER

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

BETTER? 1 Less of it 2 More Semantic 3 More Accessible 4 Futureproof // Speed // Maintainability // SEO // Happy People

Slide 5

Slide 5 text

23 1

Slide 6

Slide 6 text

HOW WUFOO DOES CSS 1

Slide 7

Slide 7 text

• No inline styles or blocks • Only 2 CSS files per page (Global + Site Section) • These 2 are made from combined smaller files (like design patterns or site sub sections) • Versioned in production (dynamic.13432.css) Timestamped in development (dynamic.TIMESTAMP.css) • Reuse everything (e.g. table.css) • Work in chunks (e.g. print.css) “RULES”

Slide 8

Slide 8 text

SIMPLIFIED SITE STRUCTURE

Slide 9

Slide 9 text

GLOBAL CSS

Slide 10

Slide 10 text

GLOBAL CSS

Slide 11

Slide 11 text

SITE SECTION CSS

Slide 12

Slide 12 text

SITE SECTION CSS

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

{autoVersion}/css/global/dynamic.css{/autoVersion} {autoVersion}/css/landing/dynamic.css{/autoVersion} Smarty function (could be any server side language)

Slide 15

Slide 15 text

AddHandler application/x-httpd-php .php .html .xml .css .js .htaccess

Slide 16

Slide 16 text

fly($dynamicURL,$fileArray); ?> /css/global/dynamic.css

Slide 17

Slide 17 text

fly($dynamicURL,$fileArray); ?> /css/landing/dynamic.css

Slide 18

Slide 18 text

1) Fetches all files 2) Minifies* 3) Combines Together* 4) Adds version number AutoVersion function:

Slide 19

Slide 19 text

Slide 20

Slide 20 text

global/dynamic.css • Loaded on every page of site • Put as much as practical in here. User only loads this file once, so maximizes use of browser cache. • Common design patterns are in here (buttons.css, lightbox.css, forms.css)

Slide 21

Slide 21 text

area/dynamic.css • Loaded in specific area of site • Less common design patterns in here (graph.css, calendar.css, table.css)

Slide 22

Slide 22 text

global /css/global/structure.css /css/global/buttons.css /css/global/lightbox.css /css/global/form.css area /css/admin/manager.css

Slide 23

Slide 23 text

area /css/widgets/datagrid.css /css/global/filter.css /css/global/calendar.css /css/global/quicksearch.css /css/entries/structure.css /css/entries/print.css global /css/global/structure.css /css/global/buttons.css /css/global/lightbox.css /css/global/form.css

Slide 24

Slide 24 text

area /css/docs/docs.css /css/global/table.css global /css/global/structure.css /css/global/buttons.css /css/global/lightbox.css /css/global/form.css

Slide 25

Slide 25 text

ALL CSS is in /css/ organized by site section

Slide 26

Slide 26 text

DON’T OVER THINK IT 2

Slide 27

Slide 27 text

• Primary color #BADA55 / Secondary color #F00 • Headers should be 20px from navigation and 15px from following content • Logo should have 30px of padding around it • Links should have 1px dotted bottom borders BIG FANCY STYLE GUIDE Good thinking Well intentioned

Slide 28

Slide 28 text

that’s what GLOBAL.CSS is for

Slide 29

Slide 29 text

NEED TO DEVIATE? Really? Do you? BY SECTION

Slide 30

Slide 30 text

STYLE ONLY NEED TO DEVIATE? Really? Do you?

Slide 31

Slide 31 text

TOTALLY UNIQUE NEED TO DEVIATE? Really? Do you?

Slide 32

Slide 32 text

DON’T OVER THINK IT /* Good thing we specified this link is a descendant of html, so none of those crazy outsider links get this style */ html body #page-wrap .inner ul li ul li a { font-size: 0.8em; } li li li li { font-size: 1.0em; /* Erm, use REM */ } a { text-decoration: none; } /* Killing a fly with a jackhammer */ #page-wrap a { text-decoration: underline; } /* Thus begins a nasty cycle */ aside a { text-decoration: none !important; }

Slide 33

Slide 33 text

CHALLENGE: Don’t use ID’s in your CSS whatsoever for one small project. Just try it

Slide 34

Slide 34 text

No content

Slide 35

Slide 35 text

PSEUDO ELEMENTS 3 :visited :hover :active :link :first-child :last-child :nth-child() :nth-of-type() :enabled :disabled :checked :indeterminate :focus :target :root :lang() pseudo class selectors http://css-tricks.com/pseudo-class-selectors/

Slide 36

Slide 36 text

:before :after

Slide 37

Slide 37 text

In
div:before { content: "Robots "; } HTML CSS In

Slide 38

Slide 38 text

In
div:before { content: "Robots "; } In div:after { content: " Disguise"; } Robots Disguise HTML CSS

Slide 39

Slide 39 text

No content

Slide 40

Slide 40 text

So what’s with the different name? Pseudo selectors select elements that already exist (perhaps in different states). Pseudo elements create new content that doesn’t exist (yet).

Slide 41

Slide 41 text

::before ::after ::first-line ::first-letter

Slide 42

Slide 42 text

:before :after :first-line :first-letter

Slide 43

Slide 43 text

In
div:before { content: "Robots "; } In div:after { content: " Disguise"; } Robots Disguise HTML CSS

Slide 44

Slide 44 text

In
Resulting HTML (sorta)

Slide 45

Slide 45 text

Robots
In
Disguise Not “before/after the element”... Resulting HTML (sorta)

Slide 46

Slide 46 text

Robots In Disguise
It’s before/after the content inside. Resulting HTML (sorta)

Slide 47

Slide 47 text

Blah blah blah

More stuff

Nothing to see here.
Resulting HTML (sorta)

Slide 48

Slide 48 text

Robots

Blah blah blah

More stuff

Nothing to see here. Disguise
Resulting HTML (sorta)

Slide 49

Slide 49 text

It’s only a model... (Not really in DOM) CAMELOT! CAMELOT! CAMELOT!

Slide 50

Slide 50 text

”Robot”
Not for “no content” elements • Allows but shouldn’t • Styles as if was inside • Checkboxes • Radio Buttons

Slide 51

Slide 51 text

BUTTONS WITH ICONS

Slide 52

Slide 52 text

CSS .button { /* Awesome gradients and stuff */ } .button img { /* Probably some margin and stuff */ } HTML ”” Visit Our Form Gallery

Slide 53

Slide 53 text

alt="" equals That’s not important. Screen readers don’t need to see that.

Slide 54

Slide 54 text

alt="" equals Then get that mothersucker out of your HTML

Slide 55

Slide 55 text

HTML CSS .button { /* Awesome gradients and stuff */ } .button-gallery:before { content: url(/images/icon_gallery.png); } Visit Our Form Gallery

Slide 56

Slide 56 text

x200 ”” Visit Our Form Gallery 200 extra lines of HTML 200 places you aren’t being semantic 200 places you need to change one-by-one 200 opportunities to be more efficient

Slide 57

Slide 57 text

No content

Slide 58

Slide 58 text

That’s a website. It’s abstract. Deal with it.

Slide 59

Slide 59 text

No content

Slide 60

Slide 60 text

CSS

Slide 61

Slide 61 text

CSS html { background: red; }

Slide 62

Slide 62 text

No content

Slide 63

Slide 63 text

No content

Slide 64

Slide 64 text

EFFICIENCY!

Slide 65

Slide 65 text

HTML CSS .button { /* Awesome gradients and stuff */ } .button-gallery:before { content: url(/images/icon_gallery.png); } Visit Our Form Gallery Individual Request

Slide 66

Slide 66 text

No content

Slide 67

Slide 67 text

Visit Our Form Gallery x200 .button-gallery:before { content: url(/images/icon_gallery.png); content: “”; display: inline-block; width: 16px; height: 16px; background-image: url(/images/sprite.png); background-position: -32px -32px; }

Slide 68

Slide 68 text

spritecow.com

Slide 69

Slide 69 text

spriteme.org

Slide 70

Slide 70 text

UNFORTUNATE NAME

Slide 71

Slide 71 text

h1:before { content: “Wufoo”; } h2:before { content: “Making forms easy + fast + fun”; } HTML CSS

Slide 72

Slide 72 text

RABBLE RABBLE RABBLE!

Slide 73

Slide 73 text

SCREEN READERS NVDA doesn’t read Jaws doesn’t read Window Eyes doesn’t read VoiceOver (OS X) does read Testing (mostly) by Lucica Ibanescu http://cssgallery.info/testing-the-accessibility-of-the-css-generated-content/

Slide 74

Slide 74 text

Bad for accessibility Bad semantically Bad for SEO

Slide 75

Slide 75 text

.thing:before { content: ? } What can content be?

Slide 76

Slide 76 text

TEXT / STRING content: “$”; content: “\0022”;

Slide 77

Slide 77 text

IMAGE content: url(i/icon-smile.png); content: -webkit-linear-gradient(...); Behaves like an Needs dimensions

Slide 78

Slide 78 text

ATTRIBUTE content: attr(href); content: attr(data-city);

Slide 79

Slide 79 text

COUNTER content: counter(li); counter-increment: li; counter-reset: li; On list On list items

Slide 80

Slide 80 text

NOTHING content: “”;

Slide 81

Slide 81 text

HTML content: “

Nope

”;

Slide 82

Slide 82 text

.price:before { content: “$”; } [lang=‘cn’] .price:before, .price[lang=‘cn’]:before { content: ‘\00a5’; }
30
100
TEXT / STRING

Slide 83

Slide 83 text

http://www.456bereastreet.com/lab/styling-ordered-list-numbers/ COUNTER ol { counter-reset: li; list-style: none; } ol > li:before { content: counter(li); counter-increment: li; background: #666; color: white; padding: 10px; }

Slide 84

Slide 84 text

COMBINING WITH MEDIA QUERIES mobile portrait

Slide 85

Slide 85 text

CSS @media (min-width: 1001px) { aside li a:after { content: " (" attr(data-email) ")"; font-size: 11px; font-style: italic; color: #666; } } @media (max-width: 1000px) and (min-width: 700px) { aside li a:before { content: "Email: "; font-style: italic; color: #666; } } @media (max-width: 699px) and (min-width: 520px), (min-width: 1151px) { aside li a { padding-left: 21px; background: url(i/email.png) left center no-repeat; } }

Slide 86

Slide 86 text

Self! You know what would be neat? You fade in pseudo elements on hover.

Slide 87

Slide 87 text

TOTAL EPIC FRICKING DISASTER

Slide 88

Slide 88 text

You can’t animate or transition pseudo elements.

Slide 89

Slide 89 text

But WAIT! You totally can in Firefox 4+

Slide 90

Slide 90 text

ATTRIBUTE a { position: relative; } a:after { content: attr(data-tooltip); position: absolute; bottom: 100%; left: 20px; background: yellow; opacity: 0; } a:hover:after { opacity: 1; } a:before { /* triangle action */ }

Slide 91

Slide 91 text

Nicolas “Dr. Pseudo Element” Gallagher http://nicolasgallagher.com/ @necolas You can’t talk about Pseudo Elements without talking about...

Slide 92

Slide 92 text

No content

Slide 93

Slide 93 text

• Multiple Backgrounds • Multiple Borders • Background Opacity • Clear Floats • Responsive Data Tables http://css-tricks.com/9516-pseudo-element-roundup/

Slide 94

Slide 94 text

Shapes! These are easy. These are less easy.

Slide 95

Slide 95 text

.star { width: 0; height: 0; border-left: 50px solid transparent; border-right: 50px solid transparent; border-bottom: 100px solid red; position: relative; } .star:after { width: 0; height: 0; border-left: 50px solid transparent; border-right: 50px solid transparent; border-top: 100px solid red; position: absolute; content: ""; top: 30px; left: -50px; }

Slide 96

Slide 96 text

http://css-tricks.com/examples/ShapesOfCSS/

Slide 97

Slide 97 text

http://nicolasgallagher.com/pure-css-gui-icons/demo/

Slide 98

Slide 98 text

Browser Support 3.5+ 3.0- positioning issues 6+ 9+ 8 :: / :hover / z-index 7- 1+ 1.3+ http://css-tricks.com/browser-support-pseudo-elements/ Remember, CSS TWO not THREE 85% CSS-Tricks 97% Other tech 92%

Slide 99

Slide 99 text

23 1

Slide 100

Slide 100 text

Links http://necolas.github.com/normalize.css/ http://snook.ca/archives/html_and_css/font-size-with-rem http://particletree.com/notebook/automatically-version-your-css-and-javascript-files/ http://css-tricks.com/855-specifics-on-css-specificity/ Photos http://www.flickr.com/photos/webel/347801397/ Type Gotham Condensed Gotham Rounded TUNGSTEN Whitney

Slide 101

Slide 101 text

Thanks! bit.ly/fowa-better-css