kslstn
kslstn

Reputation: 1656

How can I apply percentage-based positioning to background-image sprites with pure CSS?

I have an SVG sprite with icons for buttons. The icons are added to the HTML link elements as a background image.

I would like to use percentages to position the sprite, but it's confusing. With pixel-based positioning, it's easy to determine the position. Unfortunately the following happens when using percentages:

Given a sprite with 8 icons, applying 50% as offset results in the space between the 4th and 5th icon being shown in the button.

What is the right way to go here?

Upvotes: 2

Views: 894

Answers (2)

Ria Weyprecht
Ria Weyprecht

Reputation: 1275

I found this link very useful understanding how background-position works using percentage. http://blog.vjeux.com/2012/image/css-understanding-percentage-background-position.html

I think using it together with sprites is quite aweful. But using SASS/LESS as suggested can definitely save a lot of work.

Upvotes: 1

kslstn
kslstn

Reputation: 1656

The width of the sprite depends on the amount of icons (images) in the sprite: one icon should (generally) be 100% of the width of the button it has to cover. So for 8 icons:

background-position: 800%;

The offset for an icon i (first: i=1, second i=2, etc) with a total number of icons n is calculated like this:

Offset in percent = (i - 1 / n - 1) * 100%

So for the 5th icon 8 in the first row of the sprite the offset = (5-1/8-1)*100% = 57,142 %

background-position: 57.142 top;

SASS mixin:

@mixin background-position($number: 1){
    $total: 8; /* The number of icons in the sprite, placed next to one another */
    background-size: percentage($total); /* Results in 800% for 8 icons */
        background-position: percentage( ($number - 1)/($total - 1) )  top; /* My sprite has the default state in the top row, :active states in the bottom */
}

Using a pre processor like SASS offers you the flexibility to add icons to the sprite at a later stage without you having to change all previously calculated background positions.

Of course this solution works for any element with a background image, not just buttons.

Upvotes: 1

Related Questions