CSS Animations using Transitions with Conditional CSS, Stacked Rectangles

This is a somewhat elaborate example of how to use conditional CSS and transitions to create a fluid, responsive stack of rectangles that are polite enough to stack up when the screen is narrow. The idea is I’m working on is to have a menuing system that stacks when the screen shrinks.

There are three versions of this code, with menustack-onemotion.html being the simplest. I should have saved a much simpler version that didn’t have so much code, but I didn’t. You can fake it by editing all the “top”, “box-shadow”, and “transition” settings out.

To see it in action, load up one of the three pages, and then resize the window so it’s narrow. Firefox works the best. Chromium might not let you shrink the window enough, but you can zoom in and see the full effect. Konqueror doesn’t seem to support transitions, at least not with this code.

http://riceball.com/d/files/menustack-onemotion.html

http://riceball.com/d/files/menustack-progressive.html

http://riceball.com/d/files/menustack-sketch.html

<!DOCTYPE html>
<html>
    <head>
        <style type="text/css">
            body { 
                background-color: #e3e3e3;
            }
            .menu {
                border: 1px solid #ddd;
                width: 120pt;
                height: 400pt;
                background-color: white;
                position: absolute;
                margin-left: -1px;
                box-shadow: 0px 0px 0px #fff;
                transition: left 0.5s, top 0.5s, box-shadow 0.25s;
            }
            .L1 { 
                left: 5pt; 
                top: 5pt;
            }
            .L2 { 
                left: 125pt; 
                top: 5pt;
            }
            .L3 { 
                left: 245pt; 
                top: 5pt;
            }
            @media screen and (max-width: 380pt) {
                .menu {
                    border: 1px solid #eee;
                    box-shadow: 0px 1px 1px #ddd;
                }
                .L1 { 
                    left: 5pt; 
                    top: 9pt;
                }
                .L2 { 
                    left: 10pt; 
                    top: 6pt;
                    box-shadow: 0px 1px 2px #ddd;
                }
                .L3 { 
                    left: 130pt; 
                    top: 3pt;
                    box-shadow: 0px 1px 4px #ddd;
                }
            }
            @media screen and (max-width: 260pt) {
                .L1 { 
                    left: 5pt; 
                    top: 9pt;
                }
                .L2 { 
                    left: 10pt; 
                    top: 6pt;
                    box-shadow: 0px 1px 2px #ddd;
                }
                .L3 { 
                    left: 15pt; 
                    top: 3pt;
                    box-shadow: 0px 1px 4px #ddd;
                }
            }
        </style>
    </head>
    <body>
        <div class="menu L1"></div>
        <div class="menu L2"></div>
        <div class="menu last L3"></div>
    </body>
</html>

So, if you’re a programmer, this is going to look a little odd because there’s no logic that causes the magic to happen. You have to think more like an animator. Animators think in terms of “key frames”, and you can think of this animation as having three key frames.

Conditional CSS is used to define the positions of the rectangles.

@media screen and (max-width: 380pt) {...

That means if the width is less than 380pt, the following styles are applied. These styles override the styles that appeared above this rule.

Likewise, @media screen and (max-width: 260pt) {... causes additional CSS to be applied, overriding not both the above block and the original CSS.

It’s a little weird to work with CSS because the right way to code it uses this overriding behavior.

We could have written it (less elegantly) like this:


@media screen and (min-width: 380pt) {
  ... frame 1 ...
}
@media screen and (min-width: 281pt) and (max-width: 379pt) {
 ... frame 2 ...
}
@media screen and (min-width: 0pt) and (max-width: 280pt) {
 ... frame 3 ...
}

But that would be wrong.

It not only leads to more code – you’re more likely to mess up the code because you have to keep track of more things. It’s better to think like this:

  • you start with one working layout that shows everything on a big screen.
  • then you create a conditional layout that alters the original.
  • as the screen space shrinks, you need to alter the layout more.

The logic of your code should be developed separate from your drawings or HTML sketches. Your HTML sketches can be messy, but the conditional CSS code should be crafted. Plan to write the code more than one: the first version is the one you throw away.

More Tricks

The use of L1, L2, and L3 is somewhat incorrect – I could have used IDs. I didn’t because I was thinking this could be used for menus, and menus might have unique IDs, but two menus could share the same “depth” in the menu hierarchy.

It still feels like a hack to me.

The “transition” feature creates the smooth animation.

When there’s a transition property, the browser takes the new value, and then calculates tween values and applies them over the specified intervals. In this example, the conditional CSS changes the styles. (You could change styles in Javascript code, directly, or by adding classes to elements.)

The scope of a transition property is the element.

So, there you go. Not the greatest tutorial, but it’s a nice effect, and the code is pretty simple for what it does.

Leave a Reply