boywithk9 boywithk9 - 3 months ago 10
CSS Question

How to make a CSS composite scalable

With some effort, I've finally managed to make a composite CSS as seen in this fiddle:

https://jsfiddle.net/boywithk9/9L5o0rrf/14/

HTML

<div style="width: 209px">
<p><a href="http://surfcityapps.com/our-top-ten-apps-bundle/">
<div class="tile-square">
<img class="tile-square-icon tile-square-shadow" src="http://surfcityapps.com/img/bundle-tiles/icon-top10.svg">
<img class="tile-square-name tile-square-shadow" style="width: 220px; margin-left: 40px; margin-right: 40px;" src="http://surfcityapps.com/img/bundle-tiles/name-top10.svg">
<img class="tile-square-bundle tile-square-shadow" src="http://surfcityapps.com/img/bundle-tiles/bundle.svg">
<img class="tile-square-OFFsale" src="http://surfcityapps.com/img/bundle-tiles/badge-onsale.png">
</div>
</a>
</p>
</div>


CSS

div.tile-square {
position: relative;
background-image: url("http://surfcityapps.com/img/bundle-tiles/background.jpg");
background-repeat: no-repeat;
background-size: contain;
min-height: 300px;
min-width: 300px;
z-index: 1;
}

.tile-square-icon {
position: absolute;
z-index: 2;
height: 160px;
width: 160px;
margin-left: 70px;
margin-right: 70px;
top: 17px;
display: block !important;
}

div img.tile-square-name {
position: absolute;
z-index: 3;
height: 40px;
top: 215px;
display: block !important;
}

.tile-square-bundle {
position: absolute;
z-index: 4;
height: 15px;
width: 130px;
margin-left: 85px;
margin-right: 85px;
top: 265px;
display: block !important;
}

.tile-square-shadow {
-webkit-filter: drop-shadow( 1px 1px 1px rgba(0,0,0,.2) );
filter: drop-shadow( 1px 1px 1px rgba(0,0,0,.2) );
}


However, I also need to be able to scale it down in size (209px by 209px, and 300px by 300px).

The only way I was able to get the images centered was a method that specifies the sizes of the container and the components.

Now I've realized that seems to make it impossible to scale the whole thing down.

Any suggestions?

Do I have to create a second set of styles/html based on the other width?

Answer

No, never create an specific CSS styles set for an specific size.

Instead, try always to use relative sizes (with percentages).

For example: instead of width: 150px, let it be width: 39%.

In this way, you'll get that the width will be 39% of its container's width, whatever it is (even if the window gets resized).

Other good practices that I recommend to you:

  • Always prefer a simple solution instead of a complicated one.
  • Always put all the CSS styles together within the CSS sheet, and not in the style HTML attributes. This way, you will get all the styles stored in just one place, instead of an untidy bunch of declarations along the CSS and the HTML.
  • Distinguish wisely the class selectors of the id selectors: Class selectors should be used to name a set of rules that will be applicable to several elements in the page. One id selector, instead, will be used for just one element.
  • Try not to repeat the same style in different selectors. Instead, declare a class and make it common to the necessary elements (I've noticed you already respect this rule. Congratulations).
  • Try not to use absolute positioning, z-index nor important! qualifiers. A good design should not need them (of course, if it is not intrinsically complex).

Based upon these recommendations, I give you my proposal:

HTML:

I've dropped off the P element because apparently does nothing, I've added a second <div> to prove that the same CSS rules serves for different elements, and I've given a different id to each <div>.

<div id="x1">
        <a href="http://surfcityapps.com/our-top-ten-apps-bundle/">
            <div class="tile-square">
                <img class="tile-square-icon tile-square-shadow" src="http://surfcityapps.com/img/bundle-tiles/icon-top10.svg">
                <img class="tile-square-name tile-square-shadow" src="http://surfcityapps.com/img/bundle-tiles/name-top10.svg">
                <img class="tile-square-bundle tile-square-shadow" src="http://surfcityapps.com/img/bundle-tiles/bundle.svg">
                <img class="tile-square-OFFsale" src="http://surfcityapps.com/img/bundle-tiles/badge-onsale.png">
            </div>
        </a>
</div>
<div id="x2">
        <a href="http://surfcityapps.com/our-top-ten-apps-bundle/">
            <div class="tile-square">
                <img class="tile-square-icon tile-square-shadow" src="http://surfcityapps.com/img/bundle-tiles/icon-top10.svg">
                <img class="tile-square-name tile-square-shadow" src="http://surfcityapps.com/img/bundle-tiles/name-top10.svg">
                <img class="tile-square-bundle tile-square-shadow" src="http://surfcityapps.com/img/bundle-tiles/bundle.svg">
                <img class="tile-square-OFFsale" src="http://surfcityapps.com/img/bundle-tiles/badge-onsale.png">
            </div>
        </a>
</div>

CSS:

div#x1 {
    width: 20%; 
    height: 20%;
    border: solid 1px;
}

div#x2 {
    width: 53%; 
    height: 53%;
    border: solid 1px;
}

div.tile-square {
    background-image: url("http://surfcityapps.com/img/bundle-tiles/background.jpg");
    background-repeat: no-repeat;
    background-size: 100%;
    height: 100%;
    width: 100%;
}

img.tile-square-shadow {
    -webkit-filter: drop-shadow( 1px 1px 1px rgba(0,0,0,.2) );
    filter: drop-shadow( 1px 1px 1px rgba(0,0,0,.2) );
}

img.tile-square-icon {
    margin-top: 7%;
    width: 50%;
    margin-left: 25%;
}

img.tile-square-name {
    margin-top: 10%;
    width: 80%;
    margin-left: 10%;
}

img.tile-square-bundle {
    margin-top: 2%;
    margin-bottom: 2%;
    width: 35%;
    margin-left: 32%;
}

img.tile-square-OFFsale {
    position: absolute;
    visibility: hidden;
    z-index: 5;
    width: 60%;
}

As you see, I've converted all the absolute dimensions to relative.

In fact, even the width of example <div id="x1"> and <div id="x2"> are set as percentages; you can modify them (or even set a left-margin) to see that the relative aspect keeps the same.

The class selectors will be shared by the image elements, while the id selectors are intended for just the container <div> elements.