ericosg
ericosg

Reputation: 4955

Resize DIVs with background-image using CSS

I'm not one to usually ask, but I cannot seem to get this done using CSS/CSS3.

Note, i'll be happy even with a not-so-supported CSS3 style, like resize.

The jsFiddle for it.

The current unresizable code:

HTML:

<div id="boxes">
  <a id="about1" class="aboutbox" href="/property-for-sale">
  &#160;</a>
  <a id="about2" class="aboutbox" href="/why-cyprus">&#160;</a>
  <a id="about3" class="aboutbox" href="/why-zantis">&#160;</a>
  <span class="stretch">&#160;</span>
</div>

CSS:

#boxes {
    padding: 70px 0 70px 0;
    text-align: justify;
    -ms-text-justify: distribute-all-lines;
    text-justify: distribute-all-lines;
}
.aboutbox {
    padding: 0;
    margin: 0;
    display: inline-block;
    *display: inline;
    zoom: 1;
    width: 320px;
    height: 225px;
    vertical-align: top;
    text-align: left;
    background-size: auto auto;
}
#about1 {
    background:#000 url('http://zantisgroup.com.cy/templates/oneweb/images/SEA_FRONT.jpg') no-repeat center center;
}
#about2 {
    background:#000 url('http://zantisgroup.com.cy/templates/oneweb/images/SEA_FRONT.jpg') no-repeat center center;
}
#about3 {
    background:#000 url('http://zantisgroup.com.cy/templates/oneweb/images/SEA_FRONT.jpg') no-repeat center center;
}
#about1:hover {
    background:#000 url('http://zantisgroup.com.cy/templates/oneweb/images/SEA_FRONT_a.jpg') no-repeat center center;
}
#about2:hover {
    background:#000 url('http://zantisgroup.com.cy/templates/oneweb/images/SEA_FRONT_a.jpg') no-repeat center center;
}
#about3:hover {
    background:#000 url('http://zantisgroup.com.cy/templates/oneweb/images/SEA_FRONT_a.jpg') no-repeat center center;
}

If you resize the html panel, you'll see that they float as expected. I'm using a common method to distribute them equally along the parent div. I'm also using CSS to create a image button with hover effects (don't ask about the nature of the graphics ..).

I'd like to get these to resize accordingly when the html panel is resized; i.e. get the actual button to scale down and remain in one line.

I've got a working solution with jQuery, but spent my time getting this without it and got nowhere. Any ideas?

tia.

Upvotes: 0

Views: 5363

Answers (4)

Matt Coughlin
Matt Coughlin

Reputation: 18906

Aspect ratio

The main issue here is maintaining the relative dimensions of the images (the aspect ratio). A couple potential ways to do this without using JavaScript or jQuery are as follows:

  1. Using foreground images (img tags).
  2. Using calc() to make the height of the image wrapper be a fixed % of its width.

I didn't have much luck with calc(). The closest I got was attempting to make the height a fixed % of the viewport width (using the vw unit). It didn't seem very promising. I can't entirely rule out a solution being possible using calc(), but so far the only obvious CSS solution for maintaining the aspect ratio requires the use of foreground images.

Updated Demo

Hover state for foreground images

Achieving the hover effect using foreground images is fairly simple. Add a pair of images to each image wrapper, and apply the :hover pseudo-class to the wrapper to turn each image on or off as needed.

<a class="aboutbox" ...>
    <img class="off" src="..." alt=""/>
    <img class="on"  src="..." alt=""/>
</a>
...
.aboutbox:hover img.off { display: none; }
.aboutbox       img.on  { display: none; }
.aboutbox:hover img.on  { display: inline-block; }

Justifying images

The trickiest part of justifying the images is that there needs to be some whitespace between the image wrappers (in the HTML source code) for the justification to have a chance of working, for the same reason that words in a sentence need to have whitespace between them (otherwise, they'll be treated as a single word).

But whitespace between inline-block elements in the HTML source code causes 3-4px of horizontal spacing to be added between the elements (with no CSS solution available for avoiding it that's truly cross-browser and safe). That extra space, although necessary for the justification to work, is mostly likely unwanted visually and may prevent all of the images from fitting on the same line in some cases.

Here's an initial demo with a crude solution: limiting the width of each image to 31%, to allow enough room (on most screen sizes) for the whitespace between the image wrappers.

The other issue with justifying the images is that, as with text, justifying images only works if the content spans at least 2 lines. One workaround for this is to add a span tag at the end of the content with display:inline-block and width:90%. The initial demo demonstrates this.

@media queries

It's worth noting that the justification is only needed when the screen is wide enough to allow extra space between the images. @media queries can be used to only apply the justification on large screens. On small screens, the image wrappers can be floated so that there's no extra space between them.

Updated demo using @media queries

Upvotes: 2

Chris Arasin
Chris Arasin

Reputation: 516

To do this with background images as you've set it up, you have to get rid of the width setting on the each item, and size the background image with background-size: 100% 100%; To maintain the height to width proportion of the .aboutboxes, use the intrinsic ratio method here with a percentage based padding-bottom. More here: http://alistapart.com/article/creating-intrinsic-ratios-for-video

.aboutbox {
    position: relative;
    padding-bottom: 70.3125%;
    display: block;
    width: auto;
    height: 0;
    background-size: 100% 100% !important;
}

If you'd like you can include a max-width or padding on the wrapper to limit how far they stretch.

Updated your fiddle here: http://jsfiddle.net/carasin/s4pUe/11/

Just be aware of some limited IE support of background-size: http://caniuse.com/#feat=background-img-opts

Upvotes: 1

lukeocom
lukeocom

Reputation: 3243

One solution is to replace the background image with an actual image. And use css to control what image is displayed, and to resize based on the containing elements. So you wrap each link in a div, which re-sizes based on your boxes container. Using css you set the image url using the content: selector.

http://jsfiddle.net/CPNbS/6/

Your resulting html looks something like:

<div id="boxes">
    <div class="link" id="about1">
        <a class="aboutbox" href="/property-for-sale"><img /></a>
    </div>
    <div class="link" id="about2">
        <a class="aboutbox" href="/why-cyprus"><img /></a>
    </div>
    <div class="link" id="about3">
        <a class="aboutbox" href="/why-zantis"><img /></a>
    </div>
</div>

and the css:

.link{width:30%;height:100%;border:1px solid green;display: inline-block;
    *display: inline;
    zoom: 1;}

.link a{padding: 0;
    margin: 0;
    display:block;
    width: 100%;
    height:100%;
    vertical-align: top;
    text-align: left;
    background-size: auto auto;}

.link a img{max-width:100%;}

#about1 a img{
    content:url("http://zantisgroup.com.cy/templates/oneweb/images/SEA_FRONT.jpg");
}
#about2 a img{
    content:url("http://zantisgroup.com.cy/templates/oneweb/images/SEA_FRONT.jpg");
}
#about3 a img{
    content:url("http://zantisgroup.com.cy/templates/oneweb/images/SEA_FRONT.jpg");
}
#about1:hover a img,#about2:hover a img,#about3:hover a img{
content:url("http://blogs.mathworks.com/pick/files/zebrainpastelfield.png");

}

You could also use a responsive design technique by including media queries. But this is more for different devices rather than re-sizing, so does not look as 'fluid'.

Hope this helps...

Upvotes: 1

Vicky
Vicky

Reputation: 174

#boxes {
 white-space: nowrap;
}
boxes a{
 display:inline-block;
 width: 33%;
 background-size: cover;  
}

but I'd rather use img tag see http://jsfiddle.net/Vicky_007/GZMvT/14/

and you can also emulate table:

#boxes {
  display: table;
  width: 100%;
  table-layout:fixed;
}
#boxes a{
  display:table-cell;
  background-size: cover;
}

Upvotes: -1

Related Questions