Join 3,512 readers in helping fund MetaFilter (Hide)


Website question: Is this layout trick possible?
January 6, 2014 3:45 PM   Subscribe

Silly question about CSS3 background images that change size to "cover" shifting dimensions. If you have an image that changes size while snipping off the sides to cover an area, is there a good way to predict its "cover" behavior, so that a piece of HTML text can follow right along with it, so as to fit over a certain spot on the image?

I have a design based on a full-screen, hi-resolution image. Using the helpful "background-size: cover" trick, the image adjusts to fit any window size. So far so good...

The trouble is that I need a piece of text to fit over a particular spot in that image. For example, let's say it is a picture of a drive-in theater, and the HTML element needs to show up directly over the screen. But mere percentages do not seem to do the trick because of how "cover" will crop the sides of the picture as needed. I tried using responsive queries based on width, but this has been really clunky and has required entering lots of position: left numbers.

In an ideal situation, there would be some way to tag that spot, that screen, and make the dynamically-generated text show up right over it wherever it goes. But I can't think of a way to do it and I wonder if anyone on Metafilter might have a good solution. I know I've seen something similar accomplished on a website somewhere. Any help much appreciated.
posted by steinsaltz to Computers & Internet (4 answers total) 3 users marked this as a favorite
 
You could do it with javascript. Is that allowed? I'm not going to write code to do it if you want an all-CSS solution or something.
posted by tylerkaraszewski at 3:55 PM on January 6


Ok, I did it anyway. I don't guarantee this is actually correct. I haven't tested it. It's conceptually close at least.
// The element with this background.
var yourElement = someHTMLElement;

// The original dimensions of the image used as the background.
var bgImgOriginalWidth = 1000; // Or whatever.
var bgImgOriginalHeight = 1000; // Or whatever.

// Their actual heights in pixels (will be computed later).
var bgImgWidth = bgImgOriginalWidth;
var bgImgHeight = bgImgOriginalHeight;

// The current actual size of the element.
var elWidth = parseFloat(getComputedStyle(yourElement));
var elHeight = parseFloat(getComputedStyle(yourElement));

// Where you want to put your text as a fraction of the background width/height.
textDesiredPosX = 0.25;
textDesiredPosY = 0.25;


// First compute the actual size of the uncropped image, and what is being cropped.
var bgAspect = bgImgOriginalWidth / bgImgOriginalHeight;
var elAspect = elWidth / elHeight;

var cropTop = 0;
var cropLeft = 0;

// The left and right sides of the background will be cropped in this situation.
if (bgAspect > elAspect) {
  bgImgWidth = elHeight * bgAspect;
  bgImgHeight = elHeight;
  cropLeft = (bgImgWidth - elWidth) / 2;
}

// The top and bottom of the background will be cropped in this situation.
else {
  bgImgWidth = elWidth;
  bgImgHeight = elHeight * bgAspect;
  cropTop = (bgImgHeight - elHeight) / 2
}

// Where the text will actually be placed, in pixels.
textPosX = (textDesiredPosX * bgImgWidth) - cropLeft;
textPosY = (textDesiredPosY * bgImgHeight) - cropTop;

document.getElementById("yourTextElement").style.left = textPosX + "px";
document.getElementById("yourTextElement").style.top = textPosY + "px";

posted by tylerkaraszewski at 4:24 PM on January 6 [3 favorites]


I don't think this is a good use of "cover" backgrounds, for the very reason you are finding: it's really hard to predict how the image will be cropped at different sizes. For this sort of thing I would set one strict dimension (i.e. do background-size: 100% auto OR auto 100%) and then figure out the rest of the design around the background image always filling the [width/height] of the browser. Good luck!
posted by Zephyrial at 9:09 PM on January 6 [1 favorite]


Thanks, Tyler, for your generous code. At the least this is a good way to understand how much cropping is going on, because I don't really understand the background-size: cover formula.
posted by steinsaltz at 3:03 PM on January 7


« Older We are in Illinois and gripped...   |  We are creating a new front po... Newer »

You are not logged in, either login or create an account to post comments