How to use CSS3 transitions to save space

Share RGraph:   

Summary
A guide for using CSS3 transitions in conjunction with multiple canvas tags as a way to save space on your page

What do you do when you have a finite and small amount of space that you can use but need to squeeze multiple charts into it? CSS3 transitions to the rescue! The example below shows you how you can adjust the canvas tags with and height so that you can fit four canvases into the same space that a regular full size canvas takes up. The canvas tags then have some CSS that makes them respond to them getting focus, become larger and by using transitions the growing is animated.

I'll stress that the effect shown here does not use JavaScript! The trigger for the effect is when the canvas gains focus - in this case that means that you can click on them. Tabbing to the canvas tags also works as that also gives the elements focus.

Being CSS the transition effect is smooth and unjerky and CSS is also used to remove the focus outline. The code to achieve this effect is shown below.

[No canvas support] [No canvas support] [No canvas support] [No canvas support]

The necessary HTML

These are the canvas tags that the charts are drawn on. The width and height attributes on the tags stipulate the full width and height of the canvas tags (ie when they're enlarged). Though here the canvas tags are set by the CSS :focus pseudo-selector to be 90% of this. It's also necessary to add the tabindex attibute because without this the tags cannot be tabbed to and thus will not get focus.

<div id="container">
    <canvas id="cvs1" width="600" height="250" tabindex="1">[No canvas support]</canvas>
    <canvas id="cvs2" width="600" height="250" tabindex="1">[No canvas support]</canvas>
    <canvas id="cvs3" width="600" height="250" tabindex="1">[No canvas support]</canvas>
    <canvas id="cvs4" width="600" height="250" tabindex="1">[No canvas support]</canvas>
</div>

The CSS to define the sizes and transitions

The CSS is used to size the canvas tags, position them and set the transition (animation) effect that you see when you click on the tags. It also turns off the focus ring that you see when you click on the tags. See the comments below for more details.

<style>
    /**
    * This the DIV that the canvas tags are defined in. It's sized to
    * be the same size as the full sized canvases (ie 600x250). It
    * also sets the position to relative so that the canvas tags
    * that it contains can be positioned absolutely.
    */
    #container {
        position: relative;
        width: 600px;
        height: 250px;
    }

    /**
    * These styles are applied to all canvas tags. It makes them positioned
    * absolutely, turns off the focus ring (with the outline property), defines
    * the transition details (the animation effect) and sets the initial z-index
    * to zero.
    */
    #container canvas {
        outline: none;
        position: absolute;
        transition: top .5s, left .5s, width .5s, height .5s, z-index .5s, transform .25s, box-shadow .5s;
        transition-delay: .25s;
        z-index: 0;
        background-color: white;
        width: 300px;
        height: 125px;
    }

    /**
    * The following four sets of styles are applied to the canvas tags in
    * order to initially position them correctly.
    */
    #container canvas#cvs1 {
        top: 0;
        left: 0;
    }

    #container canvas#cvs2 {
        top: 0;
        left: 300px;
    }

    #container canvas#cvs3 {
        top: 125px;
        left: 0;
    }

    #container canvas#cvs4 {
        top: 125px;
        left: 300px;
    }

    /**
    * And these styles are applied when the canvas tags gain focus - which
    * in this case means when they're clicked on or tabbed to. The canvas tag is
    * positioned and sized as necessary and the z-index ordering is set to 999
    * so that it's on top. It's also given a slight shadow.
    */
    #container canvas#cvs1:focus,
    #container canvas#cvs2:focus,
    #container canvas#cvs3:focus,
    #container canvas#cvs4:focus {
        top: 5%;
        left: 5%;
        width: 90%;
        height: 90%;
        z-index: 999;
        box-shadow: 0 0 25px #ccc;
    }
</style>

The RGraph libraries and code

And finally here is the HTML to include the RGraph libraries and the JavaScript that creates the charts. There's nothing special happening here - just some basic charts.

<!--
    Include the RGraph libraries
-->
<script src="/libraries/RGraph.common.core.js" ></script>
<script src="/libraries/RGraph.bar.js" ></script>
<script src="/libraries/RGraph.line.js" ></script>
<script src="/libraries/RGraph.waterfall.js" ></script>

<!--
    This is the code that creates the charts. Since it is using
    the jQuery ready event you could put this at the top or at
    the bottom of the page. But for performance reasons you'd
    probably be better off putting it at the bottom
-->
<script>
    window.onload = (function ()
    {
        var bar = new RGraph.Bar({
            id: 'cvs1',
            data: [4,5,3,1,2,6,5,4,8],
            options: {
                labels: ['Dave','Loui','Luis','Pete','Olga','Steve','Kevin','John','Cuthbert'],
                textAccessible: false
            }
        }).wave();

        var line = new RGraph.Line({
            id: 'cvs2',
            data: [1,3,5,2,6,4,7,8,9],
            options: {
                labels: ['Dave','Loui','Luis','Pete','Olga','Steve','Kevin','John','Cuthbert'],
                gutterLeft: 35,
                gutterRight: 35,
                gutterTop: 35,
                gutterBottom: 35,
                textAccessible: false
            }
        }).trace2();

        var waterfall = new RGraph.Waterfall({
            id: 'cvs3',
            data: [45,-2,-9,4,6,3,-23,2,4],
            options: {
                labels: ['Dave','Loui','Luis','Pete','Olga','Steve','Kevin','John','Total'],
                textAccessible: false
            }
        }).grow();

        var waterfall = new RGraph.Waterfall({
            id: 'cvs4',
            data: [4,5,3,1,2,6,5,4,-8],
            options: {
                labels: ['Dave','Loui','Luis','Pete','Olga','Steve','Kevin','John','Total'],
                textAccessible: false
            }
        }).grow();
    });
</script>

Comments

Add a new comment...