Very Simple CSS-only Proportional Resizing of Elements

 

A while ago I posted about Proportional Resizing of Web Page Elements Using Only CSS. At the time, it seemed like the only solution… but fortunately a slightly counter intuitive CSS standard provides a much better way to get this same effect. Credit goes to Nathan D. Ryan for his solution on Stackoverflow.

The concept is nicely discussed in Matt Snider’s Blog Post… > Doing a little research, I was reminded that when you use percents to apply the margin of an element, the browsers determine the actual size of the margin by multiply the percent against the width of the parent node (this is true for margin-top, -right, -bottom, and -left). It is not based on either the height or width of the element that the margin is applied to. […] I was surprised to relearn that the padding is also relative to the width of the applied elements parent node. So using percentages with padding works exactly as it does with margin.

This could come in handy for a few things. It’s a good fact to note if you’re doing CSS work. For proportional resizing purposes, it makes matters extremely simple: Define the width of an element as a percentage (eg: 100%) of the parent’s width, then define the element’s padding-top (or -bottom) as a percentage so that the height is the aspect ratio you need.

For example, if I have a container with a child element like so:

<div class="container">
    <div class="child">
    </div>
</div>

I can use the following css to give the child element an aspect ratio of 4:3

.container { 
    width: 500px; /* pick whatever width you want */
}
.container .child {
    width: 100%;
    padding-top: 75%;
}

But, of course, if we put any content inside the child it will change the height and throw off our aspect ratio. So what we need is another element inside which is positioned absolutely over the child element which obtains its size. We do that like this:

<div class="container">
    <div class="outer">
        <div class="inner">Your content</div>
    </div>
</div>

and css…

.container { 
    width: 500px; /* pick whatever width you want */
}
.container .outer {
    width: 100%;
    padding-top: 75%; /* defines aspect ratio */
    position: relative;
}
.container .outer .inner {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
}

And that’s it! All in all, very intuitive solution that uses a counter intuitive feature of CSS.

Here’s the full jsFiddle:

Quick Tip: Creating a "Draw" animation with svg paths

 

Let’s say you want to create an animation that draws some kind of shape. Like watching a pencil draw a line on paper. Turns out this is really easy with SVG paths.

If you haven’t heard of SVG, you should check it out. It’s a well-supported way of creating complex shapes with DOM elements. RaphaelJS is a library that makes this process even easier by providing javascript methods to do complex drawings.

One way of creating a shape is by creating it as an SVG path. This is exactly what it sounds like. It’s a directional outline of a shape, or a way of drawing a curvy line from point A to point B. You can draw along this path with different stroke styles (solid, dashed, etc). The neat thing about creating a dashed line along a path is that you can control the length of the dashes. What happens if you make the dash as long as the line? Magic.

If you create a path, and then specify the dash length to be much greater than the path itself, you can animate the dash offset to give the effect of “drawing” along that path. Here’s how you do it:

  1. Create a path (see RaphaelJS)
  2. Set the properties: path-dasharray and path-dashoffset to be equal, and a pixel value much greater than the path itself (eg: 99999px). Let’s call this maxLen for now.
  3. Animate the path-dashoffset from its starting value, to the value of the path-dasharray minus the path length (maxLen - path length). You can use jQuery for this.

Here’s a jsFiddle showing an example of this technique.