Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to achieve this flexible layout without using JS?

Tags:

html

css

What I'm trying to achieve without using JS can be seen on jsfiddle.net/k2h5b/.

Basically I would like to display two images, both centered, one in background and one in foreground:

  • Background Image: Should cover the whole window without affecting the aspect ratio, which means that the image will always touch two opposite edges of the window, but the image will be cropped.
  • Forground Image: Should be inside the window without affecting the aspect ratio, which means the image will be always touch two opposite edges of the window, but the image will not be cropped.
  • It doesn't matter if it's a <div> or an <img> tag, as long as they are displaying the images.
  • Asume also that the image sizes are known upfront and can be used in CSS or HTML part.

So my question is: is it possible using only CSS or CSS3?

If it's not possible I will accept the answer that will be as close as possible to my goal.

Examples:

  • When the background image is cropped from the top and bottom: example when background image is cropped from top and the bottom

  • When the background image when it's cropped from left and right: example when background image is cropped from left and right

like image 254
Lipis Avatar asked Nov 01 '11 19:11

Lipis


3 Answers

After looking at @Kent Brewster's answer, I think I could achieve all the requirements of OP.

This doesn't have the problem of foreground image being cropped and you can also specify constant margin around the foreground image. Also div is being used instead of img tag, because we are using background images. Here is the link and here is the code:

<div id='bg'></div>
<div id='fg'></div>

#bg {
  position: absolute;
  height: 100%;
  width: 100%;
  background-image: url(http://i.imgur.com/iOvxJ.jpg);
  background-repeat: no-repeat;
  background-position: 50% 50%;
  background-size: cover;
}
#fg {
  position: absolute;
  top: 10px;
  left: 10px;
  bottom: 10px;
  right: 10px;
  opacity: .7;
  background-image: url(http://i.imgur.com/HP9tp.jpg);
  background-repeat: no-repeat;
  background-position: 50% 50%;
  background-size: contain;
}
like image 76
tzador Avatar answered Oct 03 '22 11:10

tzador


Try this:

<html>
<style>
body {
  margin: 0;
}
#bg {
  position: absolute;
  height: 100%;
  width: 100%;
  background: transparent url(bg.jpg) 50% 50% no-repeat;
  background-size: cover;
}
#fg {
  position: absolute;
  height: 90%;
  width: 90%;
  top: 5%;
  left: 5%;
  background: transparent url(fg.jpg) 50% 50% no-repeat;
  background-size: cover;
  opacity: .7;
}
</style>
<body>
<div id="bg"></div>
<div id="fg"></div>
</body>
</html>

If the scaling requirement is flexible, it might work. See http://jsfiddle.net/k2h5b/5/ to see it run.

like image 28
Kent Brewster Avatar answered Oct 03 '22 11:10

Kent Brewster


Yes, it's possible.

Basically I just made the background image the background for the <body> (doesn't have to be the body of course), and then put the image inside that with a small margin.

<body>
  <img id='fg' src='http://3.bp.blogspot.com/-OYlUbWqyqog/TeL-gXGx3MI/AAAAAAAAHRc/bdqvvvaeC7c/s1600/bald-eagle3.jpg'></img>
</body>

css:

body {
  margin: 0; padding: 0;
  overflow: hidden;
  background: url('http://wallpaper.zoda.ru/bd/2006/07/21/2c7b4306fd22f049f331d43adb74a5f7.jpg') no-repeat left top;
}

#fg {
  margin: 20px 20px;
  opacity: 0.7;
}

obviously if the window is too big, there'd be issues. You could (I guess) use media queries to pull in different image sizes based on window size.

edit — OK, well for the image, if you do want it to crop and retain the right aspect ratio, then I think you'll have to know the image size ahead of time to do it so that it works out. Lacking that, here's another revision.

<body>
  <div id='fg'>&nbsp;</div>
</body>

css:

body {
  margin: 0; padding: 0;
  overflow: hidden;
  background: url('http://wallpaper.zoda.ru/bd/2006/07/21/2c7b4306fd22f049f331d43adb74a5f7.jpg') no-repeat left top;
}

body, html { width: 100%; height: 100%; }

#fg {
  margin: 2%; width: 96%; height: 96%;
  opacity: 0.7;
  background: url('http://3.bp.blogspot.com/-OYlUbWqyqog/TeL-gXGx3MI/AAAAAAAAHRc/bdqvvvaeC7c/s1600/bald-eagle3.jpg') no-repeat center center;
}

If you know the image dimensions, you could then set max-height and max-width. (I'll try that too :-)

edit again To get the background to crop in a centered way, you'd need to set the position to "center center" instead of "left top". (Or "center top" if you just want it centered horizontally.)

Vertically centering elements with CSS without cutting-edge non-standard features (flexible box layout) is hard. That may be something to do with JavaScript. I'll say that one problem with any JavaScript solution like that is that it really slows the browser down. If you must do it, I would suggest introducing a little time lag so that you don't try to recompute the layout on every resize event. Instead, set a timer for like 200 milliseconds in the future where the work will get done, and each time you do so cancel the previous timer. That way, while a person is dragging the window corner it won't burn up their CPU.

edit even more ooh ooh yes @Kent Brewster's answer with the vertical centering is good - I always forget that trick :-)

like image 28
Pointy Avatar answered Oct 03 '22 12:10

Pointy