We all know that CSS3 has emerged in past couple of years a lot, and everyone is talking about it. There are many new features and properties that are well implemented in modern browsers.

But lately there has been some buzz going around CSS4. CSS Working Group has published a first working draft over half a year ago with many new proposals. CSS4 isn’t going to replace CSS3, but the work on specifications will go on parallel with CSS3 Modules.

In this article I’ll go through some of the most interesting proposals for CSS4. There are many new concepts, including such as parent selector, UI states pseudo-classes, Logical Combinations and Namespaces.

This article is based on my presentation: “CSS3 – The Present and The Future” which contains a section Peek into CSS4.

Table of Contents

Parent Selector

This is the magical selector many developers have been craving for. Earlier there hasn’t been an option to select the parent of an element. In CSS4 this is possible.

Parent selector was earlier proposed to be declared by using “$” rule, eg. $fieldset input:focus. At the moment it is proposed that the rule is following:

fieldset! > input:focus {
  background-color:yellow;
}

If you’re interested in starting to use parent selector today, check jQuery-powered polyfill: cssParentSelector for it.

UI States pseudo-classes

UI states pseudo-classes are meant to target different states an element can have. These are defined in CSS Basic User Interface Module, which have been moved into CSS4 proposal. Some of them, like :enabled and :disabled are already specified in CSS3, while others, like :valid and :invalid are new pseudo-classes in CSS.

Here is the list of UI states pseudo-classes:

  • :enabled / :disabled
  • :checked
  • :indeterminate
  • :default
  • :valid / :invalid
  • :in-range / :out-of-range
  • :required / :optional
  • :read-only / :write-only

Most of them are self-explanatory, but you can read more detailed description from the draft.

Tree-Structural pseudo-classes

Tree-structural pseudo-classes (eg. :nth-child() and :nth-of-type()) has now two new pseudo-classes: :nth-match() and :nth-last-match().

What :nth-match() actually is? It’s very similar to the logic with :nth-child().

:nth-match(an+b of selector-list) notation represents an element that has a parent and has an+b-1 siblings that match the given selector-list before it in the document tree, for any zero or positive integer value of n.

In practice, :nth-match matches with the given selector-list while :nth-child matches with the given selectors children elements. This happens by including of keyword in selector. If you have the selector input:nth-match(even of :enabled), it will first match the subset of input elements that are enabled and then match the even elements from that subset.

Logical Combinators

Logical Combinations consists of two pseudo-classes: :matches() and :not(). The behavior of “Negation pseudo-class” :not() is most likely clear to you – eg. input:not(:disabled) matches with all the input elements that are not disabled. But :matches() might be a bit more strange:

Matches-Any pseudo-class

The :matches() pseudo-class is the standardised version of Mozilla’s :-moz-any() pseudo class. This is useful for when you need a number of similar selector strings, but change one part such as the pseudo-classes.

Instead of writing a:hover, a:focus, a:active, one can write a:matches(:hover, :focus, :active) for same result.

Reference Combinators

Reference combinators allow you to select elements that are referenced by ID by another element. This is better to be explained in practice:

The following example highlights an input element when its label is focused or hovered-over:

label:matches(:hover, :focus) /for/ input { /* association by "for" attribute */
    box-shadow: yellow 0 0 10px;
}

Media Queries Level 4

While writing this article, first draft of Media Queries Level 4 was published. Unfortunately I won’t be writing more about Media Queries in this article, I just suggest reading the draft :).

Namespaces

Namespaces are actually proposed in CSS(3) Namespaces Module, but it’s written pretty much the same time as first proposal of CSS4. And CSS4 proposal is heavily referring to the namespaces, so I feel this one is good to go through when speaking of CSS4.

CSS Namespaces has quite simple syntax. The @namespace declares a namespace prefix and associates it with a given namespace name, and “vertical bar” works as a selector delimiter. Consider following example:

@namespace "http://www.example.com";
@namespace foo "http://www.example.com/foo";

h1 { font-size: 42px; } /* Belongs in example.com */
|h1 { font-size: 36px; } /* Belongs eg. in example.com/bar */
*|h1 { font-size: 32px; } /* Belongs in both namespaces */
foo|h1 { font-size: 28px; } /* Belongs in example.com/foo */

New Properties for Borders

Some new properties for borders are introduced in CSS4. The most obvious one is border-corner-shape, which allows values curve | bevel | scoop | notch. In addition, there are updates on border-images.

For further reading, see CSS Backgrounds and Borders Module Level 4.

Resources

I have to admit that there is lot more in CSS4 Working Draft than it’s included in this article. Therefore I suggest you all to read following resources I’ve gathered about CSS4:

CSS3 Transitions - Are We There Yet?
Cascading Style Sheets 3 has been available for “some time” (first time introduced nine years ago). However, CSS3 hasn’t been available in common use for more than two years. CSS3 Transitions in real use were introduced in late 2007 by Safari. At that time, they were referred as “CSS Animations”, but the terminology changed when Safari introduced their proprietary features also called CSS Animations I’ve split this topic in two articles. In this first article I’ll make a generic overview on CSS3 Transitions. Additionally, I’ll introduce some of the basic implementations and evaluate few CSS properties, meant for creating transformations and transitions. This article also contains references to excellent CSS3 articles. So after reading this article, go ahead and upgrade your knowledge about CSS3 Transitions with them.
This article is also published in Finnish, titled as “CSS3 Transitiot – olemmeko jo perillä?” at gfx.fi. Like mentioned above, the whole topic has been split in two parts. The first part is offering a general overview in current status of CSS3 Transitions. Second part is called “CSS3 Transitions – Problems and Solutions”, which will explain in details how CSS3 Transitions behave in different browsers. The first part of the article contains following sections: Getting Started

Getting Started

To get started, you’ll need a browser that supports CSS3 Transitions:

What about Internet Explorer?

At the moment it’s announced that Internet Explorer 9 isn’t going to support CSS3 Transitions. The best support for IE Transitions and Transformations can be achieved with Matrix Filter. Additionally, I recommend reading an article titled Cross-Browser Animated CSS Transforms — Even in IE, written by Zoltan “Du Lac” Hawryluk who is the author of cssSandpaper. The Basics of the Basics

The Basics of the Basics

Unfortunately, there’s no “one rule to rule them all” for transitions. Actually every browser has their own proprietary properties. Fortunately the syntax for values are consistent.

What can be transitioned?

Most properties can be transitioned and therefore I see no reason to list them here explicitly. However, there are some difference between browsers and the most obvious exception is that Firefox 3.7a doesn’t support transition of transformations at all.

The property values for transitions

Transitions have four values to declare at maximum: Shorthand:
-webkit-transition: property_name duration timing_function delay;
-moz-transition: property_name duration timing_function delay;
-o-transition: property_name duration timing_function delay;
transition: property_name duration timing_function delay;
You also can declare every value explicitly: (Target) Property:
-webkit-transition-property: property_name;
-moz-transition-property: property_name;
-o-transition-property: property_name;
transition-property: property_name;
Duration:
-webkit-transition-duration: duration;
-moz-transition-duration: duration;
-o-transition-duration: duration;
transition-duration: duration;
Duration (like delay) can be entered either in seconds (eg. 0.5s) or in milliseconds (eg. 500ms). It’s important to note that if the value is entered without suffix, transition will not work at all. Timing (of motion):
-webkit-transition-timing-function: timing_function;
-moz-transition-timing-function: timing_function;
-o-transition-timing-function: timing_function;
transition-timing-function: timing_function;
Available timing functions:
  • cubic-bezier(cp1x, cp1y, cp2x, cp2y)
  • ease – equivalent to cubic-bezier(0.25, 0.1, 0.25, 1.0).
  • linear – equivalent to cubic-bezier(0.0, 0.0, 1.0, 1.0).
  • ease-in – equivalent to cubic-bezier(0.42, 0, 1.0, 1.0).
  • ease-out – equivalent to cubic-bezier(0, 0, 0.58, 1.0).
  • ease-in-out – equivalent to cubic-bezier(0.42, 0, 0.58, 1.0).
Delay:
-webkit-transition-delay: delay;
-moz-transition-delay: delay;
-o-transition-delay: delay;
-transition-delay: delay;
Delay (like duration) can be entered either in seconds (eg. 0.5s) or in milliseconds (eg. 500ms). In general, it’s good to declare transitions on default state selectors without pseudo classes. This will cause transition played in both direction, eg. when hovering. Remember, you have to enter all the properties four times before being cross-browser compliant. Therefore it’d be best to use shorthand codes for keeping your CSS code clean. The Basics

The Basics

Now, I’m going to demonstrate some of the transitions. You must either hover or to click activation buttons for displaying transitions. All the code examples below has no browser proprietary format written – this is for saving space.

Basic Transition: Dimensions and Scaling

I’ll start by demonstrating the basic transition. It also demonstrates the difference between width+height and scale transform.
#widthHeight	{transition:all 500ms;}
#widthHeight:hover	{width:200px;height:200px;line-height:200px;}

#scale	{transition:all 500ms;}
#scale:hover	{transform:scale(2.0, 2.0);}
Width + Height
Scale
 

As you can see, width and height increases normally while scaling is treated almost like absolutely positioned element. On scaling, the transform-origin is set to middle while modifying width+height origin is on the top-left corner.

Transition with Timing Function

Below there are two blocks rotating; one with linear timing-function and second one with ease.
#rotateLinear	{position:relative;clear:both;left:0px;
		transition:all 2500ms linear;}
		
#rotateEasing	{position:relative;clear:both;left:0px;
		transition:all 2500ms ease;}
		
#rotateLinear:target	{left:200px;
			transform:rotate(360deg);}

#rotateEasing:target {left:200px;
			transform:rotate(360deg);}
Linear
Easing
 
Activate LinearActivate Easing
 

As you probably noticed, the movement is different but both transitions ends at the same time (after 2500ms).

Transition with Delay

Delays are useful in some cases. And they’re very easy to implement in transitions:

#bgColorDelay	{background-color:#12142B;
		transition:background-color 500ms linear 800ms;}
#bgColorDelay:hover	{background-color:#336699;}
800ms delay
 

Transition Chaining

Transitions can also be chained. This doesn’t come as a default feature, but chaining can be achieved by adding delay between transitions:

#widthHeightOpacity	{transition:width 500ms, height 500ms linear 500ms, opacity 500ms linear 1000ms;}
#widthHeightOpacity:hover	{width:200px;height:200px;opacity:0.1;}
w+h+opacity
 

This has one caveat: transitions are displayed in same order no matter whether the element is hovered or it’s in default state. And that makes no sense. Therefore we need to reverse the declarations (compared to earlier examples) as following:

#widthHeightOpacity	{
	transition:width 500ms 1000ms, height 500ms linear 500ms, opacity 500ms linear;
}

#widthHeightOpacity:hover	{width:200px;height:200px;opacity:0.1;
	transition:width 500ms, height 500ms linear 500ms, opacity 500ms linear 1000ms;
}

Is There Anything Else?

Well of course, there might be something else I haven’t noticed at this point. But what I’m trying to emphasize is that transitions are rather simple to implement (although they require a bit extra work for cross-browser compliancy).

Conclusions

Conclusions

Are we there yet? Yes, we’re over halfway there. Transitions in general are very cool in proper use. However, I’m personally still bit skeptic with CSS3 Transitions: at this point, you can’t rely on them and you must do cross-browser testing thoroughly. I’ll cover some of the problems at the following part of this article series. And I’m also going to briefly compare CSS3 Transitions with jQuery Animations. If you’re dealing with a platform solely running on WebKit (like iPhone or Adobe AIR) then go ahead and enjoy the full power of both CSS3 Transitions and WebKit animations. External Resources

External Resources

Here are some good resources provided both by browser vendors and other external authors. I strongly suggest reading them for adopting transitions and other CSS3 techniques.

Comments?

Feel free to comment any part of the article. Additionally, if you know good resources about CSS3 Transitions, go ahead and contribute.

UPDATE

This project is updated! Visit the GitHub Project Page for details.


I was about not to publish anything before Christmas – just calming down, taking some extra time to get my blog design finished, plugins installed, and so on..

..but no. I got way too excited when I heard today that Opera 10.5 pre-alpha for Labs was released. In other words, this means that an updated version of Opera’s layout engine, Presto, was out to play with – meaning, that CSS3 Transformations and Transitions are available also for Opera.

In this article, we write some lines of CSS and create rotating transform effect with all the common browsers, including Internet Explorer and the latest version of Opera.

Issues with Opera and IE

Opera offers CSS3 Transitions support in Opera Presto 2.3, at least partially. By the specification, we’re able to take advantage of -o-transform:rotate(deg);.

IE is a bit trickier (big surprise). Fortunately there’s a nice filter available, called Matrix. The values for matrix are quite complicated, hence some assistance with Javascript is needed.

In my case, I’ve created some functionality and bound it with HTC file to CSS selectors. The functionality is based on values of property -ms-transformation. I’ve also implemented -ms-transition for transitions, but this will be examined further on later posts.

Example code

In this example, I’ll be using A-elements for hover support in IE6. I’ve already written a small implementation similar to Whatever:hover, but that “project” is still taking baby steps.

So let’s cut the chase and create some lines of code:

HTML

<a href="#" id="one" class="rotate">This is 45deg -rotated element.</a>
<a href="#" id="two" class="rotate">This is 10deg -rotated element, which rotates to 45deg when hovered.</a>

CSS

#one	{
  behavior:url(-ms-transform.htc);
  -moz-transform:rotate(45deg);
  -webkit-transform:rotate(45deg);
  -o-transform:rotate(45deg);
  -ms-transform:rotate(45deg);
}
#two	{
  behavior:url(-ms-transform.htc);
  -moz-transform:rotate(10deg);
  -webkit-transform:rotate(10deg);
  -o-transform:rotate(10deg);
  -ms-transform:rotate(10deg);
}
#two:hover	{
  -moz-transform:rotate(45deg);
  -webkit-transform:rotate(45deg);
  -o-transform:rotate(45deg);
  -ms-transform:rotate(45deg);
}

Demo

You can view demo at Demo section: Cross-browser Rotation Transformation with CSS.

Final thoughts

Although everything “is not fully there”, this article shows the possibility for implementing cross-browser CSS3 Transformations purely with CSS.

In addition, this post works as an opening post of my blog. Feel free to give feedback. Merry Christmas!