CSS3 Interactive Interfaces
This week, I'm lucky enough to speak at CSS Dev Conference in Honolulu, Hawaii. I've worked on my deck pretty substantially since SXSW. Of all the slides, I have two favorites. My first favorite slide quotes The Princess Bride. My second favorite slide has only a couple words:
Why JS?
This is CSS Dev Conference
CSS3 Interfaces
Driven by a desire to see what types of interfaces can be easily ported to CSS3, I spent some time coding up rudimentary demos. Each one of these shows functionality that is typically implemented using JavaScript.
HTML and CSS Replacing JS
HTML and CSS have evolved. This is relatively obvious. However, what is interesting is the way in which HTML and CSS evolve.
HTML and CSS are designed around marking up and displaying content better on the web. This is the heart of web standards: to create languages that can deliver information to users on all sorts of different devices around the world. Because of this, the languages evolve new features to answer common patterns.
Since early versions of HTML and CSS, these languages replace functionality that was once only possible with JavaScript, or with other client- or server-side technologies. Think about the things we can do now with HTML and CSS that wasn't available just a few years ago:
:hover
and:active
psuedo classes allow the addition and manipulation of text styles like underlines and colors as well as background images.- Fixed backgrounds and elements allow developers to dock UI pieces to the sides of the browser.
- Adding
:hover
to non-anchor elements can create multi-level dropdown menus. - CSS3 offers syntax for rounded corners, gradients, and alpha transparency, all replacing complex graphical techniques.
- Adding grey placeholder text to a form input is possible with HTML5.
As HTML5 gets better-implemented, we see further transitions from the world of JS. HTML5 form validation, date pickers, and rich number selectors will all further extend HTML5's power.
CSS3 Psuedo Classes
CSS3 adds many selectors to CSS2.1's selector language. Here are some of the most interesting selectors (yes, some of these are CSS2.1 selectors, but they remain under-utilized):
- :target applies to the element which has an identifier matching any target from the URL. So, if the url was .../mypage.html#nav, the element in mypage.html with the id of 'nav' would have its :target styles applied.
- :checked applies to radio buttons and checkboxes which are checked.
- + selects the adjascent sibling of a certain element type.
h1 + h2 {color: red}
would turn any h2's that immediately follow an h1 red. - ~ selects any younger sibling of a certain element.
h1 ~ p {color: red}
would turn all p's that follow an h1 at the same level of the DOM red.
:target
The :target
psueo class is extremely handy for adding styles to elements that have been targeted by clicking on an anchor tag. Anchors that take the user to another section of the page have been widely since HTML's early days. However, the ability to style these elements offeres new possibilities.
A simple example of this could be to visually highlight a targeted seection. This could be done by adding a light background to the header, or subtly darkening the header of the text. This may help orient users if there are lots of sections in quick succession.
However, :target
also holds the key to many pure-CSS implementations of interfaces that usualy require JavaScript. In two of the demos (tabs and accordions) :target
is used to display the correct section, whether it is part of a tab or of an accordion.
:target can also be used in order to power CSS-based modal popovers. The contents of the modal should be hidden from view, and then displayed as soon as the anchor associated with the modal is clicked.
:checked
In a similar vein to :target
is :checked
. Instead of actuating on a change in the page's URI, it actuates when a checkbox or radio button is checked or highlighted.
This can give an added benefit if manipulating the URL is something that you don't want to do, or if you need to actuate more than one thing at a time. This is because multiple checkboxes can be checked at a time, or even multiple radio buttons provided they do not share the same name. :target
can only affect one element at a time.
Because of this, we can use :checked
in order to create accordions where more than one pane can be open at a time.
:checked powers the tray and the first two of the accordion demos.
Since form elements can be ungainly when used for UI controls, you may want to actuate the checkbox and radio buttons via a label tag. A label tag should have a for attribute that matches the form element's id attribute.
Siblings (+
, ~
)
However, when working with the :checked
psuedo class, we often don't want to style the checkbox or radio button directly. Instead, we want to hide the form element and change how the label, article, or some other element looks. To do this, we'll often need to use sibling selectors.
So, to style the label after an input, we can use:
input:checked + label { color: #900; } /* OR */ input:checked + article { display: block; }
However, each element can only have one next element, so you can't do both of the above. And, unfortunately, at the time of writing (December, 2012) some of these selectors can lead to bad performance, even on advanced browsers (Chrome) and solid hardware. So, the following does not work well:
input:checked + label { color: #900; } input:checked + label + article { /* DO NOT USE */ display: block; }
Instead, a better solution to chaining element selectors is to either use the general younger sibling selector, or have a DOM node that contains both the label and article immediately after the checkbox. Both these solutions work, and I use the latter in the accordion demos. The former technique requires knowing there will only be one article following the checked at the same level of the DOM.
input:checked + label { color: #900; } input:checked ~ article { display:block; } /* OR */ input:checked + section label { color: #900; } input:checked + section article { display:block; }