Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Writing Better HTML & CSS

Chris Coyier
October 07, 2011

Writing Better HTML & CSS

First we define "better", then we tackle that in three stages. Starting high-level, the CSS architecture of Wufoo. Then we get slightly more specific by not "overthinking" our selectors. Then we get into some nuts and bolts CSS talking about my favorite thing: pseudo elements.

Chris Coyier

October 07, 2011
Tweet

More Decks by Chris Coyier

Other Decks in Design

Transcript

  1. WRITING
    BETTER HTML
    & CSS

    View full-size slide

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

    View full-size slide

  3. HOW WUFOO
    DOES CSS
    1

    View full-size slide

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

    View full-size slide

  5. SIMPLIFIED SITE STRUCTURE

    View full-size slide

  6. SITE SECTION CSS

    View full-size slide

  7. SITE SECTION CSS

    View full-size slide



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

    View full-size slide

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

    View full-size slide

  10. require_once($GLOBALS['root'].'/library/services/
    AutoVersion.php');
    $fileArray = array(
    '/css/global/structure.css',
    '/css/global/buttons.css',
    '/css/global/lightbox.css',
    '/css/global/form.css'
    );
    $av = new AutoVersion();
    $av->fly($dynamicURL,$fileArray);
    ?>
    /css/global/dynamic.css

    View full-size slide

  11. require_once($GLOBALS['root'].'/library/services/
    AutoVersion.php');
    $fileArray = array(
    '/css/landing/structure.css',
    '/css/landing/table.css',
    '/css/landing/else.css',
    '/css/landing/signup.css',
    '/css/landing/tour.css'
    );
    $av = new AutoVersion();
    $av->fly($dynamicURL,$fileArray);
    ?>
    /css/landing/dynamic.css

    View full-size slide

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

    View full-size slide

  13. 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)

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  16. 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

    View full-size slide

  17. 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

    View full-size slide

  18. ALL
    CSS
    is in /css/
    organized by
    site section

    View full-size slide

  19. DON’T OVER
    THINK IT
    2

    View full-size slide

  20. • 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

    View full-size slide

  21. that’s what
    GLOBAL.CSS
    is for

    View full-size slide

  22. NEED TO DEVIATE?
    Really? Do you?
    BY
    SECTION

    View full-size slide

  23. STYLE
    ONLY
    NEED TO DEVIATE?
    Really? Do you?

    View full-size slide

  24. TOTALLY
    UNIQUE
    NEED TO DEVIATE?
    Really? Do you?

    View full-size slide

  25. 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;
    }

    View full-size slide

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

    View full-size slide

  27. 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/

    View full-size slide

  28. :before
    :after

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  31. 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).

    View full-size slide

  32. ::before
    ::after
    ::first-line ::first-letter

    View full-size slide

  33. :before
    :after
    :first-line :first-letter

    View full-size slide

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

    View full-size slide


  35. In

    Resulting
    HTML
    (sorta)

    View full-size slide

  36. Robots

    In

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

    View full-size slide


  37. Robots
    In
    Disguise

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

    View full-size slide


  38. Blah blah blah
    More stuff
    Nothing to see here.

    Resulting
    HTML
    (sorta)

    View full-size slide


  39. Robots
    Blah blah blah
    More stuff
    Nothing to see here.
    Disguise

    Resulting
    HTML
    (sorta)

    View full-size slide

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

    View full-size slide





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

    View full-size slide

  42. BUTTONS
    WITH ICONS

    View full-size slide

  43. CSS
    .button {
    /* Awesome gradients and stuff */
    }
    .button img {
    /* Probably some margin and stuff */
    }
    HTML


    Visit Our Form Gallery

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    Visit Our Form Gallery

    View full-size slide

  47. 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

    View full-size slide


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

    View full-size slide

  49. CSS
    html {
    background: red;
    }

    View full-size slide

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

    Visit Our Form Gallery

    Individual Request

    View full-size slide


  51. 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;
    }

    View full-size slide

  52. spritecow.com

    View full-size slide

  53. spriteme.org

    View full-size slide

  54. UNFORTUNATE
    NAME

    View full-size slide



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

    View full-size slide

  56. RABBLE RABBLE RABBLE!

    View full-size slide

  57. 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/

    View full-size slide

  58. Bad for accessibility
    Bad semantically
    Bad for SEO

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  64. NOTHING
    content: “”;

    View full-size slide

  65. HTML
    content: “Nope”;

    View full-size slide

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

    View full-size slide

  67. 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;
    }

    View full-size slide

  68. COMBINING WITH MEDIA QUERIES
    mobile portrait

    View full-size slide

  69. 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; }
    }

    View full-size slide

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

    View full-size slide

  71. TOTAL
    EPIC
    FRICKING
    DISASTER

    View full-size slide

  72. You can’t animate
    or transition
    pseudo elements.

    View full-size slide

  73. But WAIT!
    You totally can
    in Firefox 4+

    View full-size slide

  74. 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 */
    }

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  77. Shapes!
    These are easy.
    These are less easy.

    View full-size slide

  78. .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;
    }

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  81. 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%

    View full-size slide

  82. 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

    View full-size slide

  83. Thanks!
    bit.ly/fowa-better-css

    View full-size slide