SlideShare a Scribd company logo
1 of 72
Download to read offline
Aaron Gustafson presents



  Solving CSS
   Problems
with eCSStender
Where in the world is CSS3?
Progress
               elements
               attributes



100


75


50


25


0

      HTML 1
Progress
                        elements
                        attributes



100


75


50


25


0

      HTML 1   HTML 2
Progress
                                 elements
                                 attributes



100


75


50


25


0

      HTML 1   HTML 2   HTML 3
Progress
                                            elements
                                            attributes



100


75


50


25


0

      HTML 1   HTML 2   HTML 3   HTML 3.2
Progress
                                                        elements
                                                        attributes



100


75


50


25


0

      HTML 1   HTML 2   HTML 3   HTML 3.2     HTML 4
                                            HTML 4.01
                                             XHTML 1
Progress
                                                        elements
                                                        attributes



100


75


50


25


0

      HTML 1   HTML 2   HTML 3   HTML 3.2    HTML 4     HTML 5
                                            HTML 4.01
                                             XHTML 1
Progress?
                                                                              elements
                                                                              attributes



100




                                                                                   HTML 5
                   HTML 3




75
                                       HTML 4




                                                HTML 4.01



                                                             XHTML 1
50
                            HTML 3.2
         HTML 2
HTML 1




25


0

                  1995                                      2000       2005     Future
CSS 2.1 became a candidate
recommendation last month
Some modules of CSS3 have
been in development
since 1999
Where does CSS
 come from?
Officially?
Officially?



Semi-officially


    ®         ®   ®
Officially?



Semi-officially


    ®           ®                 ®
  -moz-   -webkit-   -ms-   -o-
Browsers “extend” CSS

           opacity



         border-radius




         column-count
Browsers “extend” CSS

           -moz-opacity


         -moz-border-radius
       -webkit-border-radius
        -khtml-border-radius



        -moz-column-count
Browsers “extend” CSS
      #foo {
        border-radius: 3px;
      }
Browsers “extend” CSS
      #foo {
        -moz-border-radius: 3px;
        -webkit-border-radius: 3px;
        -o-border-radius: 3px;
        -khtml-border-radius: 3px;
      }
Browsers “extend” CSS
      #foo {
        border-radius: 10px 5px;
      }
Browsers “extend” CSS
      #foo {
        -moz-border-radius: 10px 5px;
        -webkit-border-top-left-radius: 10px;
        -webkit-border-top-right-radius: 5px;
        -webkit-border-bottom-right-radius: 10px;
        -webkit-border-bottom-left-radius: 10px;
        -o-border-radius: 10px 5px;
        -khtml-border-top-left-radius: 10px;
        -khtml-border-top-right-radius: 5px;
        -khtml-border-bottom-right-radius: 10px;
        -khtml-border-bottom-left-radius: 10px;
      }
Browsers “extend” CSS
      #foo {
        padding: 10px;
        width: 200px;
        width: 180px;
        height: 200px;
        height: 180px;
      }

      /* or */

      #foo {
        padding: 10px;
        width: 200px;
        height: 200px;
      }
      * html #foo {
        width: 180px;
        height: 180px;
      }
Can we play too?
First Experiment: 2005
     #content:before {
       -gfss-source: url(spiral.swf);
       -gfss-background-color: #000;
       -gfss-flash-version: 6;
       -gfss-quality: high;
       -gfss-flash-vars: "foo=bar&bar=foo";
       -gfss-width: 50;
       -gfss-height: 50;
       position: absolute;
       top: 0;
       left: 0;
     }
First Experiment: 2005
3 years later...
Fast facts
๏   It’s pronounced “extender”
๏   A small JS library (<16K mini ed) for interfacing with CSS
๏   Is library agnostic (plays well with anyone)
๏   MIT License
๏   Enables both
    ‣ the creation of CSS extensions to push the boundaries
      of the language (experimentally or practically), and
    ‣ the patching of old/outdated browsers to the latest standards
๏   Allows designers to include extensions in their site and
    have their CSS Just Work.
Fast facts
๏   It’s media aware (including @media)
๏   It can handle both linked and imported CSS (nesting too)
๏   It understands concepts like @font-face and @page
๏   It runs on DOM ready (undetectably in many cases)
๏   Its CSS parser functions much like a browser’s,
    paying attention to the two key concepts:
    ‣ Speci city
    ‣ Cascade
๏   It supports local storage (window.localStorage and IE’s UserData)
    for client-side caching
How does it work?


 eCSStender.register(
   { selector: 'h1' },
   '*',
   function( selector, properties, media, specificity ){
     // do something
   });
How does it work?


 eCSStender.register(
   { selector: 'h1' },
   '*',
   function( selector, properties, media, specificity ){
     // do something
   });




         extension registration
How does it work?


 eCSStender.register(
   { selector: 'h1' },
   '*',
   function( selector, properties, media, specificity ){
     // do something
   });




          de ne the extension
How does it work?


 eCSStender.register(
   { selector: 'h1' },
   '*',
   function( selector, properties, media, specificity ){
     // do something
   });




             property request
How does it work?


 eCSStender.register(
   { selector: 'h1' },
   '*',
   function( selector, properties, media, specificity ){
     // do something
   });




              callback function
In prose
๏   Search for a selector containing “h1”
๏   Collect every property set on it
๏   Send each selector, its properties, media type and speci city to my
    function so I can do something with it.

       eCSStender.register(
         { selector: 'h1' },
         '*',
         function( selector, properties, media, specificity ){
           // do something
         });
Do you want to
see something
     cool?
#sidebar {
  width: 30%;
  float: right;
  position: relative;
  transform-origin: 0 0;
  transform: rotate(-15);
}
Finding what
  you want
The definition
๏   Requires a lookup method
    ‣ selector
     - simple selector string:      { selector: 'h1' }

     - compound selector string:    { selector: 'h1, h2' }

     - regular expression:          { selector: /s*h1s*/ }

     - array of any of the above:   { selector: [ 'h1', /s*h1s*/ ] }

     - a selector function:
       {
           selector: function(){
             return ( this.match(/s*h1s*/) !== null );
           }
       }
The definition
๏   Requires a lookup method
    ‣ property
     - simple string:      { property: 'border-radius' }

     - array of strings:   { property: [ 'border-radius' ] }

    ‣ fragment             { fragment: 'radius' }
    ‣ prefix               { prefix: 'moz' }
The definition
๏   Can be
    ‣ media-restricted:
       {
           selector: 'h1',
           media: 'screen, projection'
       }

    ‣ ltered by property name or value:
       {
           property: 'transform',
           filter: {
             value: /rotate(-?d+?)/
           }
       }
The definition
๏   Can be
    ‣ ngerprinted:
       {
           fragment:    'radius',
           fingerprint: 'net.easy-designs.border-radius'
       }
Getting what
 you want
Properties, please.
๏   eCSStender tries to be smart about properties you want
    ‣ property-based lookups (property, fragment, pre x)
      always return the matching properties, allowing you to
      supply false as the second argument of register()
       eCSStender.register(
        {
           fragment:    'radius',
           fingerprint: 'net.easy-designs.border-radius'
        },
        false,
        function(){});
Properties, please.
๏   You can still specify what you want though
    ‣ Get every property on the matching element using “*”
       eCSStender.register(
        { selector: 'h1' },
        '*',
        function(){});

    ‣ or you can specify the properties you want using a string:
       eCSStender.register(                eCSStender.register(
        { selector: 'h1' },         or      { selector: 'h1' },
        'color',                            ['color','visibility'],
        function(){});                      function(){});
Doing something
with what you find
The callback
๏   When matches are found, your callback function is run
๏   eCSStender supplies your callback function with the following
    four arguments (in order)
    ‣ selector - the selector that was matched
    ‣ properties - a hash of the desired properties from a match
    ‣ medium - the medium in which the match was found
    ‣ speci city - a sum-total of the selector’s speci city
The callback
 eCSStender.register(
  { selector: 'h1' },
  '*',
  function( selector, properties, medium, specificity ){

    alert( 'my extension found ' + selector );

    if ( typeof properties['color'] != 'undefined' )
    {
      alert ( 'this h1 has a color!' );
    }

    alert( 'the medium is ' + medium );

    alert( 'it has a specificity of ' + specificity );

  });
Testing
Testing
 1-2-3
It’s wishful thinking...
๏   but what happens when browsers start doing things correctly?
๏   eCSStender helps you prepare by supporting robust testing
    for selector and property support: eCSStender.isSupported()
    ‣ test for property support*:
       eCSStender.isSupported( 'property',
                               'border-top-left-radius: 3px' );
It’s wishful thinking...
๏   but what happens when browsers start doing things correctly?
๏   eCSStender helps you prepare by supporting robust testing
    for selector and property support: eCSStender.isSupported()
    ‣ test for property support*:
       eCSStender.isSupported( 'property',
                               'border-top-left-radius: 3px' );


     * pay attention to how browsers store values    !
It’s wishful thinking...
๏   but what happens when browsers start doing things correctly?
๏   eCSStender helps you prepare by supporting robust testing
    for selector and property support: eCSStender.isSupported()
    ‣ test for selector support:
       var
       div = document.createElement('div'),
       p    = document.createElement('p'),
       p2   = p.cloneNode(true);
       div.appendChild( p ); div.appendChild( p2 );
       eCSStender.isSupported( 'selector', 'div p ~ p',
                               div, p2 );


                        html context    element that this
                                          should select
Where to test
๏   Testing can be useful in many places
    ‣ The test property of your extension de nition (true == run):
       eCSStender.register(
         { selector: /:empty/,
            test:     function(){
              var
              div = document.createElement('div'),
              p    = document.createElement('p');
              div.appendChild( p );
              return ( ! eCSStender.isSupported(
                'selector', 'div p:empty', div, p ) );
            }
         },
         ...
Where to test
๏   Testing can be useful in many places
    ‣ Within your callback function:
       eCSStender.register( ... function( ... ){ ...
           if ( ( eCSStender.isSupported( 'selector',
                     'p:nth-child(odd)', div, p ) &&
                  ! eCSStender.isSupported( 'selector',
                       'p:nth-child(2n+1)', div, p ) &&
                  selector.match(
                    /:nth-child(s*(?:even|odd)s*)/ ) != null )
                || eCSStender.isSupported( 'selector',
                      'p:nth-child(2n+1)', div, p ) ){
             // support is incomplete, but fixable
           } else {
             // we need to compensate for no support
           }
         });
Helpers
Working with styles
๏   Basic premise in eCSStender: applying inline style sucks
    and should be avoided because it
    ‣ has the greatest speci city
    ‣ runs roughshod over the cascade
Working with styles
๏   eCSStender encourages other methods of style application:
    ‣ eCSStender.embedCSS()
     - takes 2 arguments: the styles to apply and (optionally) the
       medium to which to apply them
       var styles = 'h1 { color: red; } h2 { color: pink; }';
       eCSStender.embedCSS( styles );

                                   or
       var styles = 'h1 { color: red; } h2 { color: pink; }';
       eCSStender.embedCSS( styles, 'screen' );
Working with styles
๏   eCSStender encourages other methods of style application:
    ‣ eCSStender.newStyleElement()
     - allows for the creation of your own embedded stylesheet
     - takes two optional string arguments: the medium and id to apply
     - returns a reference to the style element
    ‣ eCSStender.addRules()
     - takes two arguments: the style element and the styles to add
       var myCSS = eCSStender.newStyleElement(),
       styles = 'h1 { color: red; } h2 { color: pink; }';
       eCSStender.addRules( myCSS, styles );
Working with styles
๏   Sometimes, however, you can’t avoid applying inline style,
    so eCSStender tries to make it better
๏   eCSStender.applyWeightedStyle() takes 3 arguments:

    ‣ a reference to the element
    ‣ an JSON object containing the properties to apply
    ‣ the speci city with which to apply them
    ‣ keeps track of the speci city with which each property is
      applied in order to facilitate smarter inline style application
Working with styles
๏   Sometimes, however, you can’t avoid applying inline style,
    so eCSStender tries to make it better
       eCSStender.applyWeightedStyle( el,
         { 'visibility': 'hidden' }, 10 );        // el is hidden

       eCSStender.applyWeightedStyle( el,
         { 'visibility': 'visible' }, 1 );        // el is still hidden

       eCSStender.applyWeightedStyle( el,
         { 'visibility': 'visible' }, 10 ); // el is visible

       eCSStender.applyWeightedStyle( el,
         { 'visibility': 'hidden' }, 100 ); // el is hidden again
Fonts and pages
๏   eCSStender exposes various “@“ rules, including
    ‣ @font-face as an object in the eCSStender.fonts array

     CSS:
       @font-face {
         font-family: 'Comfortaa';
         font-weight: normal;
         src: url('/fonts/Comfortaa_Regular');
       }

     eCSStender.fonts:

       [ { 'font-family': 'Comfortaa',
           'font-weight': 'normal',
           src:           "url('/fonts/Comfortaa_Regular')" } ]
Fonts and pages
๏   eCSStender exposes various “@“ rules, including
    ‣ @page as a property of the eCSStender.pages object

     CSS:
       @page {
         margin: 3cm;
       }
       @page :right {
         margin-left: 5cm;
       }

     eCSStender.pages:

       {
           all: { margin: '3cm' },
           right: { 'margin-left': '5cm' }
       }
Performance
๏   eCSStender tries to be smart about which stylesheets it
    pays attention to and which it doesn’t
    ‣ foreign stylesheets are always ignored
    ‣ you can tell eCSStender to ignore speci c on-site stylesheets
       eCSStender.ignore('foo.css');
       eCSStender.ignore(['foo.css', 'bar.css']);

๏   eCSStender will attempt to cache extensions and the rules
    they apply to automatically, but you can disable that
       eCSStender.disableCache();
Advanced eCSStender
๏   Use eCSStender.lookup() to gain introspection into the stylesheets
    from your callback function
    ‣ lookup by selector, property, fragment or pre x
    ‣ restrict results by medium and/or speci city
       matches = eCSStender.lookup(
         {
            selector:    'h1',
            specificity: 0     // max specificity
         },
         '*'
       ); // matches.length === 0
Advanced eCSStender
๏   Use eCSStender.lookup() to gain introspection into the stylesheets
    from your callback function
    ‣ lookup by selector, property, fragment or pre x
    ‣ restrict results by medium and/or speci city
       matches = eCSStender.lookup(
          {
             selector:    'h1',
             specificity: { min: 0, max: 2 }
          },
          '*'
       );
Advanced eCSStender
๏   Use eCSStender.lookup() to gain introspection into the stylesheets
    from your callback function
    ‣ lookup by selector, property, fragment or pre x
    ‣ restrict results by medium and/or speci city
    ‣ returns an array of style objects:
       [ { medium:          'all'
           selector:        'h1',
           specificity:     1
           properties:      { color: 'red' }
         }, ... ]
Advanced eCSStender
๏   Create new eCSStender methods
       eCSStender.addMethod('myMethod',function(){
         alert('hello');
       });
       eCSStender.methods.myMethod();
       eCSStender.methods['myMethod']();

๏   Supply custom functions to be run when eCSStender nishes
       eCSStender.onComplete(function({
         alert('eCSStender is finished processing!');
       });
Let’s make an
  extension
Solving CSS Problems with eCSStender
                     by Aaron Gustafson

                     Slides available at
          http://slideshare.net/AaronGustafson

           This presentation is licensed under
                   Creative Commons
      Attribution-Noncommercial-Share Alike 3.0

                        eCSStender
                   http://eCSStender.org

                    flickr Photo Credits
                       “Photo plate 5” by SophieG*
  “World Map 1689 — No. 1” by Caveman 92223 — Great to be Home
                “Calendar Card - January” by Joe Lanman
        “Wheeled School Bus - Right Front” by Bill Ward's Brickpile
                     “Röck!! on the right” by Adactio
http:// ickr.com/photos/aarongustafson/galleries/72157622372250877/

More Related Content

What's hot

What's hot (10)

Neo4j: Import and Data Modelling
Neo4j: Import and Data ModellingNeo4j: Import and Data Modelling
Neo4j: Import and Data Modelling
 
Introductionto fp with groovy
Introductionto fp with groovyIntroductionto fp with groovy
Introductionto fp with groovy
 
SenchaCon 2016: Developing COSMOS Using Sencha Ext JS 5 - Shenglin Xu
SenchaCon 2016: Developing COSMOS Using Sencha Ext JS 5 - Shenglin XuSenchaCon 2016: Developing COSMOS Using Sencha Ext JS 5 - Shenglin Xu
SenchaCon 2016: Developing COSMOS Using Sencha Ext JS 5 - Shenglin Xu
 
Working With a Real-World Dataset in Neo4j: Import and Modeling
Working With a Real-World Dataset in Neo4j: Import and ModelingWorking With a Real-World Dataset in Neo4j: Import and Modeling
Working With a Real-World Dataset in Neo4j: Import and Modeling
 
Kotlin Basics - Apalon Kotlin Sprint Part 2
Kotlin Basics - Apalon Kotlin Sprint Part 2Kotlin Basics - Apalon Kotlin Sprint Part 2
Kotlin Basics - Apalon Kotlin Sprint Part 2
 
Graph abstraction
Graph abstractionGraph abstraction
Graph abstraction
 
CSS for Developers
CSS for DevelopersCSS for Developers
CSS for Developers
 
The Ring programming language version 1.10 book - Part 103 of 212
The Ring programming language version 1.10 book - Part 103 of 212The Ring programming language version 1.10 book - Part 103 of 212
The Ring programming language version 1.10 book - Part 103 of 212
 
JAX 09 - OSGi on Scala
JAX 09 - OSGi on ScalaJAX 09 - OSGi on Scala
JAX 09 - OSGi on Scala
 
OSGi DevCon 09 - OSGi on Scala
OSGi DevCon 09 - OSGi on ScalaOSGi DevCon 09 - OSGi on Scala
OSGi DevCon 09 - OSGi on Scala
 

Viewers also liked

Sheffield
SheffieldSheffield
Sheffield
daveyp
 
Nutze die Macht @ IKT-Forum 09 Linz
Nutze die Macht @ IKT-Forum 09 LinzNutze die Macht @ IKT-Forum 09 Linz
Nutze die Macht @ IKT-Forum 09 Linz
Eric Eggert
 

Viewers also liked (11)

Insta gis
Insta gisInsta gis
Insta gis
 
[PREMONEY 2014] Gunderson Dettmer >> Joshua Cook, "The Wind-Down Round: Navig...
[PREMONEY 2014] Gunderson Dettmer >> Joshua Cook, "The Wind-Down Round: Navig...[PREMONEY 2014] Gunderson Dettmer >> Joshua Cook, "The Wind-Down Round: Navig...
[PREMONEY 2014] Gunderson Dettmer >> Joshua Cook, "The Wind-Down Round: Navig...
 
StackCommerce
StackCommerceStackCommerce
StackCommerce
 
Sheffield
SheffieldSheffield
Sheffield
 
Reaching More for Less [PSU May 2011]
Reaching More for Less [PSU May 2011]Reaching More for Less [PSU May 2011]
Reaching More for Less [PSU May 2011]
 
New developments in Web Accessibility
New developments in Web AccessibilityNew developments in Web Accessibility
New developments in Web Accessibility
 
Nutze die Macht @ IKT-Forum 09 Linz
Nutze die Macht @ IKT-Forum 09 LinzNutze die Macht @ IKT-Forum 09 Linz
Nutze die Macht @ IKT-Forum 09 Linz
 
Юрий Робул Experience Marketing: процессы эффективного маркетинга
Юрий Робул Experience Marketing: процессы эффективного маркетингаЮрий Робул Experience Marketing: процессы эффективного маркетинга
Юрий Робул Experience Marketing: процессы эффективного маркетинга
 
JISC LIDP ILI2011
JISC LIDP ILI2011JISC LIDP ILI2011
JISC LIDP ILI2011
 
"The Startup's Guide to Customer Retention," Retention Science >> Jerry Jao [...
"The Startup's Guide to Customer Retention," Retention Science >> Jerry Jao [..."The Startup's Guide to Customer Retention," Retention Science >> Jerry Jao [...
"The Startup's Guide to Customer Retention," Retention Science >> Jerry Jao [...
 
500’s Demo Day Batch 12 >> Lish
500’s Demo Day Batch 12 >> Lish 500’s Demo Day Batch 12 >> Lish
500’s Demo Day Batch 12 >> Lish
 

Similar to Solving CSS Problems With eCSStender - An Event Apart - Chicago 2009

Even faster web sites presentation 3
Even faster web sites presentation 3Even faster web sites presentation 3
Even faster web sites presentation 3
Felipe Lavín
 
HTML5 and CSS3 – exploring mobile possibilities - Frontend Conference Zürich
HTML5 and CSS3 – exploring mobile possibilities - Frontend Conference ZürichHTML5 and CSS3 – exploring mobile possibilities - Frontend Conference Zürich
HTML5 and CSS3 – exploring mobile possibilities - Frontend Conference Zürich
Robert Nyman
 
Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011
Chris Alfano
 

Similar to Solving CSS Problems With eCSStender - An Event Apart - Chicago 2009 (20)

Massimo Artizzu - The tricks of Houdini: a magic wand for the future of CSS -...
Massimo Artizzu - The tricks of Houdini: a magic wand for the future of CSS -...Massimo Artizzu - The tricks of Houdini: a magic wand for the future of CSS -...
Massimo Artizzu - The tricks of Houdini: a magic wand for the future of CSS -...
 
Css3
Css3Css3
Css3
 
Even faster web sites presentation 3
Even faster web sites presentation 3Even faster web sites presentation 3
Even faster web sites presentation 3
 
HTML5 and CSS3 – exploring mobile possibilities - Frontend Conference Zürich
HTML5 and CSS3 – exploring mobile possibilities - Frontend Conference ZürichHTML5 and CSS3 – exploring mobile possibilities - Frontend Conference Zürich
HTML5 and CSS3 – exploring mobile possibilities - Frontend Conference Zürich
 
HTML 5 & CSS 3
HTML 5 & CSS 3HTML 5 & CSS 3
HTML 5 & CSS 3
 
HTML5 and CSS3: Exploring Mobile Possibilities - London Ajax Mobile Event
HTML5 and CSS3: Exploring Mobile Possibilities - London Ajax Mobile EventHTML5 and CSS3: Exploring Mobile Possibilities - London Ajax Mobile Event
HTML5 and CSS3: Exploring Mobile Possibilities - London Ajax Mobile Event
 
What I discovered about layout vis CSS Grid
What I discovered about layout vis CSS GridWhat I discovered about layout vis CSS Grid
What I discovered about layout vis CSS Grid
 
A brief look at CSS3 techniques by Aaron Rodgers, Web Designer @ vzaar.com
A brief look at CSS3 techniques by Aaron Rodgers, Web Designer @ vzaar.comA brief look at CSS3 techniques by Aaron Rodgers, Web Designer @ vzaar.com
A brief look at CSS3 techniques by Aaron Rodgers, Web Designer @ vzaar.com
 
Implementing Awesome: An HTML5/CSS3 Workshop
Implementing Awesome: An HTML5/CSS3 WorkshopImplementing Awesome: An HTML5/CSS3 Workshop
Implementing Awesome: An HTML5/CSS3 Workshop
 
Accelerated Stylesheets
Accelerated StylesheetsAccelerated Stylesheets
Accelerated Stylesheets
 
Jsf2 html5-jazoon
Jsf2 html5-jazoonJsf2 html5-jazoon
Jsf2 html5-jazoon
 
Refresh Tallahassee: The RE/MAX Front End Story
Refresh Tallahassee: The RE/MAX Front End StoryRefresh Tallahassee: The RE/MAX Front End Story
Refresh Tallahassee: The RE/MAX Front End Story
 
Ease into HTML5 and CSS3
Ease into HTML5 and CSS3Ease into HTML5 and CSS3
Ease into HTML5 and CSS3
 
CSS and CSS3
CSS and CSS3CSS and CSS3
CSS and CSS3
 
It's a Mod World - A Practical Guide to Rocking Modernizr
It's a Mod World - A Practical Guide to Rocking ModernizrIt's a Mod World - A Practical Guide to Rocking Modernizr
It's a Mod World - A Practical Guide to Rocking Modernizr
 
The Creative New World of CSS
The Creative New World of CSSThe Creative New World of CSS
The Creative New World of CSS
 
Demystifying HTML5
Demystifying HTML5Demystifying HTML5
Demystifying HTML5
 
Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011
 
Introduccion a HTML5
Introduccion a HTML5Introduccion a HTML5
Introduccion a HTML5
 
html5
html5html5
html5
 

More from Aaron Gustafson

More from Aaron Gustafson (20)

Delivering Critical Information and Services [JavaScript & Friends 2021]
Delivering Critical Information and Services [JavaScript & Friends 2021]Delivering Critical Information and Services [JavaScript & Friends 2021]
Delivering Critical Information and Services [JavaScript & Friends 2021]
 
Adapting to Reality [Guest Lecture, March 2021]
Adapting to Reality [Guest Lecture, March 2021]Adapting to Reality [Guest Lecture, March 2021]
Adapting to Reality [Guest Lecture, March 2021]
 
Designing the Conversation [Beyond Tellerrand 2019]
Designing the Conversation [Beyond Tellerrand 2019]Designing the Conversation [Beyond Tellerrand 2019]
Designing the Conversation [Beyond Tellerrand 2019]
 
Getting Started with Progressive Web Apps [Beyond Tellerrand 2019]
Getting Started with Progressive Web Apps [Beyond Tellerrand 2019]Getting Started with Progressive Web Apps [Beyond Tellerrand 2019]
Getting Started with Progressive Web Apps [Beyond Tellerrand 2019]
 
Progressive Web Apps: Where Do I Begin?
Progressive Web Apps: Where Do I Begin?Progressive Web Apps: Where Do I Begin?
Progressive Web Apps: Where Do I Begin?
 
Media in the Age of PWAs [ImageCon 2019]
Media in the Age of PWAs [ImageCon 2019]Media in the Age of PWAs [ImageCon 2019]
Media in the Age of PWAs [ImageCon 2019]
 
Adapting to Reality [Starbucks Lunch & Learn]
Adapting to Reality [Starbucks Lunch & Learn]Adapting to Reality [Starbucks Lunch & Learn]
Adapting to Reality [Starbucks Lunch & Learn]
 
Conversational Semantics for the Web [CascadiaJS 2018]
Conversational Semantics for the Web [CascadiaJS 2018]Conversational Semantics for the Web [CascadiaJS 2018]
Conversational Semantics for the Web [CascadiaJS 2018]
 
Better Performance === Greater Accessibility [Inclusive Design 24 2018]
Better Performance === Greater Accessibility [Inclusive Design 24 2018]Better Performance === Greater Accessibility [Inclusive Design 24 2018]
Better Performance === Greater Accessibility [Inclusive Design 24 2018]
 
PWA: Where Do I Begin? [Microsoft Ignite 2018]
PWA: Where Do I Begin? [Microsoft Ignite 2018]PWA: Where Do I Begin? [Microsoft Ignite 2018]
PWA: Where Do I Begin? [Microsoft Ignite 2018]
 
Designing the Conversation [Concatenate 2018]
Designing the Conversation [Concatenate 2018]Designing the Conversation [Concatenate 2018]
Designing the Conversation [Concatenate 2018]
 
Designing the Conversation [Accessibility DC 2018]
Designing the Conversation [Accessibility DC 2018]Designing the Conversation [Accessibility DC 2018]
Designing the Conversation [Accessibility DC 2018]
 
Performance as User Experience [AEADC 2018]
Performance as User Experience [AEADC 2018]Performance as User Experience [AEADC 2018]
Performance as User Experience [AEADC 2018]
 
The Web Should Just Work for Everyone
The Web Should Just Work for EveryoneThe Web Should Just Work for Everyone
The Web Should Just Work for Everyone
 
Performance as User Experience [AEA SEA 2018]
Performance as User Experience [AEA SEA 2018]Performance as User Experience [AEA SEA 2018]
Performance as User Experience [AEA SEA 2018]
 
Performance as User Experience [An Event Apart Denver 2017]
Performance as User Experience [An Event Apart Denver 2017]Performance as User Experience [An Event Apart Denver 2017]
Performance as User Experience [An Event Apart Denver 2017]
 
Advanced Design Methods 1, Day 2
Advanced Design Methods 1, Day 2Advanced Design Methods 1, Day 2
Advanced Design Methods 1, Day 2
 
Advanced Design Methods 1, Day 1
Advanced Design Methods 1, Day 1Advanced Design Methods 1, Day 1
Advanced Design Methods 1, Day 1
 
Designing the Conversation [Paris Web 2017]
Designing the Conversation [Paris Web 2017]Designing the Conversation [Paris Web 2017]
Designing the Conversation [Paris Web 2017]
 
Exploring Adaptive Interfaces [Generate 2017]
Exploring Adaptive Interfaces [Generate 2017]Exploring Adaptive Interfaces [Generate 2017]
Exploring Adaptive Interfaces [Generate 2017]
 

Recently uploaded

Recently uploaded (20)

Intro in Product Management - Коротко про професію продакт менеджера
Intro in Product Management - Коротко про професію продакт менеджераIntro in Product Management - Коротко про професію продакт менеджера
Intro in Product Management - Коротко про професію продакт менеджера
 
Buy Epson EcoTank L3210 Colour Printer Online.pdf
Buy Epson EcoTank L3210 Colour Printer Online.pdfBuy Epson EcoTank L3210 Colour Printer Online.pdf
Buy Epson EcoTank L3210 Colour Printer Online.pdf
 
10 Differences between Sales Cloud and CPQ, Blanka Doktorová
10 Differences between Sales Cloud and CPQ, Blanka Doktorová10 Differences between Sales Cloud and CPQ, Blanka Doktorová
10 Differences between Sales Cloud and CPQ, Blanka Doktorová
 
Optimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through ObservabilityOptimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through Observability
 
ASRock Industrial FDO Solutions in Action for Industrial Edge AI _ Kenny at A...
ASRock Industrial FDO Solutions in Action for Industrial Edge AI _ Kenny at A...ASRock Industrial FDO Solutions in Action for Industrial Edge AI _ Kenny at A...
ASRock Industrial FDO Solutions in Action for Industrial Edge AI _ Kenny at A...
 
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdfIntroduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
 
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
 
Enterprise Knowledge Graphs - Data Summit 2024
Enterprise Knowledge Graphs - Data Summit 2024Enterprise Knowledge Graphs - Data Summit 2024
Enterprise Knowledge Graphs - Data Summit 2024
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
 
The Metaverse: Are We There Yet?
The  Metaverse:    Are   We  There  Yet?The  Metaverse:    Are   We  There  Yet?
The Metaverse: Are We There Yet?
 
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
 
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdfThe Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
 
Buy Epson EcoTank L3210 Colour Printer Online.pptx
Buy Epson EcoTank L3210 Colour Printer Online.pptxBuy Epson EcoTank L3210 Colour Printer Online.pptx
Buy Epson EcoTank L3210 Colour Printer Online.pptx
 
Introduction to Open Source RAG and RAG Evaluation
Introduction to Open Source RAG and RAG EvaluationIntroduction to Open Source RAG and RAG Evaluation
Introduction to Open Source RAG and RAG Evaluation
 
Designing for Hardware Accessibility at Comcast
Designing for Hardware Accessibility at ComcastDesigning for Hardware Accessibility at Comcast
Designing for Hardware Accessibility at Comcast
 
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
 
Demystifying gRPC in .Net by John Staveley
Demystifying gRPC in .Net by John StaveleyDemystifying gRPC in .Net by John Staveley
Demystifying gRPC in .Net by John Staveley
 
AI presentation and introduction - Retrieval Augmented Generation RAG 101
AI presentation and introduction - Retrieval Augmented Generation RAG 101AI presentation and introduction - Retrieval Augmented Generation RAG 101
AI presentation and introduction - Retrieval Augmented Generation RAG 101
 
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdfLinux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
 
Extensible Python: Robustness through Addition - PyCon 2024
Extensible Python: Robustness through Addition - PyCon 2024Extensible Python: Robustness through Addition - PyCon 2024
Extensible Python: Robustness through Addition - PyCon 2024
 

Solving CSS Problems With eCSStender - An Event Apart - Chicago 2009

  • 1. Aaron Gustafson presents Solving CSS Problems with eCSStender
  • 2. Where in the world is CSS3?
  • 3. Progress elements attributes 100 75 50 25 0 HTML 1
  • 4. Progress elements attributes 100 75 50 25 0 HTML 1 HTML 2
  • 5. Progress elements attributes 100 75 50 25 0 HTML 1 HTML 2 HTML 3
  • 6. Progress elements attributes 100 75 50 25 0 HTML 1 HTML 2 HTML 3 HTML 3.2
  • 7. Progress elements attributes 100 75 50 25 0 HTML 1 HTML 2 HTML 3 HTML 3.2 HTML 4 HTML 4.01 XHTML 1
  • 8. Progress elements attributes 100 75 50 25 0 HTML 1 HTML 2 HTML 3 HTML 3.2 HTML 4 HTML 5 HTML 4.01 XHTML 1
  • 9. Progress? elements attributes 100 HTML 5 HTML 3 75 HTML 4 HTML 4.01 XHTML 1 50 HTML 3.2 HTML 2 HTML 1 25 0 1995 2000 2005 Future
  • 10. CSS 2.1 became a candidate recommendation last month
  • 11. Some modules of CSS3 have been in development since 1999
  • 12. Where does CSS come from?
  • 15. Officially? Semi-officially ® ® ® -moz- -webkit- -ms- -o-
  • 16. Browsers “extend” CSS opacity border-radius column-count
  • 17. Browsers “extend” CSS -moz-opacity -moz-border-radius -webkit-border-radius -khtml-border-radius -moz-column-count
  • 18. Browsers “extend” CSS #foo { border-radius: 3px; }
  • 19. Browsers “extend” CSS #foo { -moz-border-radius: 3px; -webkit-border-radius: 3px; -o-border-radius: 3px; -khtml-border-radius: 3px; }
  • 20. Browsers “extend” CSS #foo { border-radius: 10px 5px; }
  • 21. Browsers “extend” CSS #foo { -moz-border-radius: 10px 5px; -webkit-border-top-left-radius: 10px; -webkit-border-top-right-radius: 5px; -webkit-border-bottom-right-radius: 10px; -webkit-border-bottom-left-radius: 10px; -o-border-radius: 10px 5px; -khtml-border-top-left-radius: 10px; -khtml-border-top-right-radius: 5px; -khtml-border-bottom-right-radius: 10px; -khtml-border-bottom-left-radius: 10px; }
  • 22. Browsers “extend” CSS #foo { padding: 10px; width: 200px; width: 180px; height: 200px; height: 180px; } /* or */ #foo { padding: 10px; width: 200px; height: 200px; } * html #foo { width: 180px; height: 180px; }
  • 23. Can we play too?
  • 24. First Experiment: 2005 #content:before { -gfss-source: url(spiral.swf); -gfss-background-color: #000; -gfss-flash-version: 6; -gfss-quality: high; -gfss-flash-vars: "foo=bar&bar=foo"; -gfss-width: 50; -gfss-height: 50; position: absolute; top: 0; left: 0; }
  • 27.
  • 28. Fast facts ๏ It’s pronounced “extender” ๏ A small JS library (<16K mini ed) for interfacing with CSS ๏ Is library agnostic (plays well with anyone) ๏ MIT License ๏ Enables both ‣ the creation of CSS extensions to push the boundaries of the language (experimentally or practically), and ‣ the patching of old/outdated browsers to the latest standards ๏ Allows designers to include extensions in their site and have their CSS Just Work.
  • 29. Fast facts ๏ It’s media aware (including @media) ๏ It can handle both linked and imported CSS (nesting too) ๏ It understands concepts like @font-face and @page ๏ It runs on DOM ready (undetectably in many cases) ๏ Its CSS parser functions much like a browser’s, paying attention to the two key concepts: ‣ Speci city ‣ Cascade ๏ It supports local storage (window.localStorage and IE’s UserData) for client-side caching
  • 30. How does it work? eCSStender.register( { selector: 'h1' }, '*', function( selector, properties, media, specificity ){ // do something });
  • 31. How does it work? eCSStender.register( { selector: 'h1' }, '*', function( selector, properties, media, specificity ){ // do something }); extension registration
  • 32. How does it work? eCSStender.register( { selector: 'h1' }, '*', function( selector, properties, media, specificity ){ // do something }); de ne the extension
  • 33. How does it work? eCSStender.register( { selector: 'h1' }, '*', function( selector, properties, media, specificity ){ // do something }); property request
  • 34. How does it work? eCSStender.register( { selector: 'h1' }, '*', function( selector, properties, media, specificity ){ // do something }); callback function
  • 35. In prose ๏ Search for a selector containing “h1” ๏ Collect every property set on it ๏ Send each selector, its properties, media type and speci city to my function so I can do something with it. eCSStender.register( { selector: 'h1' }, '*', function( selector, properties, media, specificity ){ // do something });
  • 36. Do you want to see something cool?
  • 37. #sidebar { width: 30%; float: right; position: relative; transform-origin: 0 0; transform: rotate(-15); }
  • 38.
  • 39.
  • 40.
  • 41. Finding what you want
  • 42. The definition ๏ Requires a lookup method ‣ selector - simple selector string: { selector: 'h1' } - compound selector string: { selector: 'h1, h2' } - regular expression: { selector: /s*h1s*/ } - array of any of the above: { selector: [ 'h1', /s*h1s*/ ] } - a selector function: { selector: function(){ return ( this.match(/s*h1s*/) !== null ); } }
  • 43. The definition ๏ Requires a lookup method ‣ property - simple string: { property: 'border-radius' } - array of strings: { property: [ 'border-radius' ] } ‣ fragment { fragment: 'radius' } ‣ prefix { prefix: 'moz' }
  • 44. The definition ๏ Can be ‣ media-restricted: { selector: 'h1', media: 'screen, projection' } ‣ ltered by property name or value: { property: 'transform', filter: { value: /rotate(-?d+?)/ } }
  • 45. The definition ๏ Can be ‣ ngerprinted: { fragment: 'radius', fingerprint: 'net.easy-designs.border-radius' }
  • 47. Properties, please. ๏ eCSStender tries to be smart about properties you want ‣ property-based lookups (property, fragment, pre x) always return the matching properties, allowing you to supply false as the second argument of register() eCSStender.register( { fragment: 'radius', fingerprint: 'net.easy-designs.border-radius' }, false, function(){});
  • 48. Properties, please. ๏ You can still specify what you want though ‣ Get every property on the matching element using “*” eCSStender.register( { selector: 'h1' }, '*', function(){}); ‣ or you can specify the properties you want using a string: eCSStender.register( eCSStender.register( { selector: 'h1' }, or { selector: 'h1' }, 'color', ['color','visibility'], function(){}); function(){});
  • 50. The callback ๏ When matches are found, your callback function is run ๏ eCSStender supplies your callback function with the following four arguments (in order) ‣ selector - the selector that was matched ‣ properties - a hash of the desired properties from a match ‣ medium - the medium in which the match was found ‣ speci city - a sum-total of the selector’s speci city
  • 51. The callback eCSStender.register( { selector: 'h1' }, '*', function( selector, properties, medium, specificity ){ alert( 'my extension found ' + selector ); if ( typeof properties['color'] != 'undefined' ) { alert ( 'this h1 has a color!' ); } alert( 'the medium is ' + medium ); alert( 'it has a specificity of ' + specificity ); });
  • 53. It’s wishful thinking... ๏ but what happens when browsers start doing things correctly? ๏ eCSStender helps you prepare by supporting robust testing for selector and property support: eCSStender.isSupported() ‣ test for property support*: eCSStender.isSupported( 'property', 'border-top-left-radius: 3px' );
  • 54. It’s wishful thinking... ๏ but what happens when browsers start doing things correctly? ๏ eCSStender helps you prepare by supporting robust testing for selector and property support: eCSStender.isSupported() ‣ test for property support*: eCSStender.isSupported( 'property', 'border-top-left-radius: 3px' ); * pay attention to how browsers store values !
  • 55. It’s wishful thinking... ๏ but what happens when browsers start doing things correctly? ๏ eCSStender helps you prepare by supporting robust testing for selector and property support: eCSStender.isSupported() ‣ test for selector support: var div = document.createElement('div'), p = document.createElement('p'), p2 = p.cloneNode(true); div.appendChild( p ); div.appendChild( p2 ); eCSStender.isSupported( 'selector', 'div p ~ p', div, p2 ); html context element that this should select
  • 56. Where to test ๏ Testing can be useful in many places ‣ The test property of your extension de nition (true == run): eCSStender.register( { selector: /:empty/, test: function(){ var div = document.createElement('div'), p = document.createElement('p'); div.appendChild( p ); return ( ! eCSStender.isSupported( 'selector', 'div p:empty', div, p ) ); } }, ...
  • 57. Where to test ๏ Testing can be useful in many places ‣ Within your callback function: eCSStender.register( ... function( ... ){ ... if ( ( eCSStender.isSupported( 'selector', 'p:nth-child(odd)', div, p ) && ! eCSStender.isSupported( 'selector', 'p:nth-child(2n+1)', div, p ) && selector.match( /:nth-child(s*(?:even|odd)s*)/ ) != null ) || eCSStender.isSupported( 'selector', 'p:nth-child(2n+1)', div, p ) ){ // support is incomplete, but fixable } else { // we need to compensate for no support } });
  • 59. Working with styles ๏ Basic premise in eCSStender: applying inline style sucks and should be avoided because it ‣ has the greatest speci city ‣ runs roughshod over the cascade
  • 60. Working with styles ๏ eCSStender encourages other methods of style application: ‣ eCSStender.embedCSS() - takes 2 arguments: the styles to apply and (optionally) the medium to which to apply them var styles = 'h1 { color: red; } h2 { color: pink; }'; eCSStender.embedCSS( styles ); or var styles = 'h1 { color: red; } h2 { color: pink; }'; eCSStender.embedCSS( styles, 'screen' );
  • 61. Working with styles ๏ eCSStender encourages other methods of style application: ‣ eCSStender.newStyleElement() - allows for the creation of your own embedded stylesheet - takes two optional string arguments: the medium and id to apply - returns a reference to the style element ‣ eCSStender.addRules() - takes two arguments: the style element and the styles to add var myCSS = eCSStender.newStyleElement(), styles = 'h1 { color: red; } h2 { color: pink; }'; eCSStender.addRules( myCSS, styles );
  • 62. Working with styles ๏ Sometimes, however, you can’t avoid applying inline style, so eCSStender tries to make it better ๏ eCSStender.applyWeightedStyle() takes 3 arguments: ‣ a reference to the element ‣ an JSON object containing the properties to apply ‣ the speci city with which to apply them ‣ keeps track of the speci city with which each property is applied in order to facilitate smarter inline style application
  • 63. Working with styles ๏ Sometimes, however, you can’t avoid applying inline style, so eCSStender tries to make it better eCSStender.applyWeightedStyle( el, { 'visibility': 'hidden' }, 10 ); // el is hidden eCSStender.applyWeightedStyle( el, { 'visibility': 'visible' }, 1 ); // el is still hidden eCSStender.applyWeightedStyle( el, { 'visibility': 'visible' }, 10 ); // el is visible eCSStender.applyWeightedStyle( el, { 'visibility': 'hidden' }, 100 ); // el is hidden again
  • 64. Fonts and pages ๏ eCSStender exposes various “@“ rules, including ‣ @font-face as an object in the eCSStender.fonts array CSS: @font-face { font-family: 'Comfortaa'; font-weight: normal; src: url('/fonts/Comfortaa_Regular'); } eCSStender.fonts: [ { 'font-family': 'Comfortaa', 'font-weight': 'normal', src: "url('/fonts/Comfortaa_Regular')" } ]
  • 65. Fonts and pages ๏ eCSStender exposes various “@“ rules, including ‣ @page as a property of the eCSStender.pages object CSS: @page { margin: 3cm; } @page :right { margin-left: 5cm; } eCSStender.pages: { all: { margin: '3cm' }, right: { 'margin-left': '5cm' } }
  • 66. Performance ๏ eCSStender tries to be smart about which stylesheets it pays attention to and which it doesn’t ‣ foreign stylesheets are always ignored ‣ you can tell eCSStender to ignore speci c on-site stylesheets eCSStender.ignore('foo.css'); eCSStender.ignore(['foo.css', 'bar.css']); ๏ eCSStender will attempt to cache extensions and the rules they apply to automatically, but you can disable that eCSStender.disableCache();
  • 67. Advanced eCSStender ๏ Use eCSStender.lookup() to gain introspection into the stylesheets from your callback function ‣ lookup by selector, property, fragment or pre x ‣ restrict results by medium and/or speci city matches = eCSStender.lookup( { selector: 'h1', specificity: 0 // max specificity }, '*' ); // matches.length === 0
  • 68. Advanced eCSStender ๏ Use eCSStender.lookup() to gain introspection into the stylesheets from your callback function ‣ lookup by selector, property, fragment or pre x ‣ restrict results by medium and/or speci city matches = eCSStender.lookup( { selector: 'h1', specificity: { min: 0, max: 2 } }, '*' );
  • 69. Advanced eCSStender ๏ Use eCSStender.lookup() to gain introspection into the stylesheets from your callback function ‣ lookup by selector, property, fragment or pre x ‣ restrict results by medium and/or speci city ‣ returns an array of style objects: [ { medium: 'all' selector: 'h1', specificity: 1 properties: { color: 'red' } }, ... ]
  • 70. Advanced eCSStender ๏ Create new eCSStender methods eCSStender.addMethod('myMethod',function(){ alert('hello'); }); eCSStender.methods.myMethod(); eCSStender.methods['myMethod'](); ๏ Supply custom functions to be run when eCSStender nishes eCSStender.onComplete(function({ alert('eCSStender is finished processing!'); });
  • 71. Let’s make an extension
  • 72. Solving CSS Problems with eCSStender by Aaron Gustafson Slides available at http://slideshare.net/AaronGustafson This presentation is licensed under Creative Commons Attribution-Noncommercial-Share Alike 3.0 eCSStender http://eCSStender.org flickr Photo Credits “Photo plate 5” by SophieG* “World Map 1689 — No. 1” by Caveman 92223 — Great to be Home “Calendar Card - January” by Joe Lanman “Wheeled School Bus - Right Front” by Bill Ward's Brickpile “Röck!! on the right” by Adactio http:// ickr.com/photos/aarongustafson/galleries/72157622372250877/