Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Relative height and width but absolute positioned x, y

I have a huge horizontal scrolling website. Think of a Mario World, as an example. Every "asset" is positioned absolute.

I would like to have the size (height and width) of the items to be relative to the browser's viewport (so using percentages) but need to position the items using actual pixels from the left etc.

When I do this, obviously, the assets are correctly resized as I resize my browser window. But the positions of the items are in pixels, so things move out of place in relation to the background.

Is there a simple CSS solution to this problem? Using percentages to define the position (left: 50% for example) is not really a good solution since it's not very accurate (see jsfiddle below). Or should I look at the resize event using JS and do something that way? If so, how?

I'm not sure if I'm making sense right now.. so let me know if there are any questions.

Edit

Here's a JSFiddle: http://jsfiddle.net/BZ77t/

Note that when you resize the window, the black block (#blockpx) is positioned using pixels and therefor not affected during resizing. The red block (#blockpercentage), however, is sized and positioned using percentages, achieving the effect I want: sticking to the intended position (which is the position of the background image). However, it's not really accurate – which does not matter that much in this example, but in a bigger setting (wider width), the difference gets quite high.

like image 860
dandoen Avatar asked Feb 21 '13 09:02

dandoen


1 Answers

The solution is to use a combination of a containing element and javascript: http://jsfiddle.net/KaaXg/3/

This fiddle includes this javascript functionality:

$(document).ready(function(){
    $(".container").css("width", $(".image").width());        
    $(window).resize(function(){
        $(".container").css("width", $(".image").width());        
    });
});

The most important thing to note here is that left and width values were being calculated with respect to the body element, which was unintended.

To counter this, we've added a containing element which contains the image and other div tags used for the red block graphics on the page.

However, without javascript, the left attribute still only "updates" when the page is reloaded after the window has been resized. Block level elements do not update horizontally on their own.

So you want the left and width to be proportional to the background image, but they won't update as the page is resized or moved around using only CSS. The javascript solution above updates the width of the containing element dynamically as the page is resized, solving this problem.

I left the bottom and height css styles alone, since they work as intended for the purposes of your website, the container grows in height to accomodate the image within it.

I'm not exactly sure what you want to do with the fixed-pixel black block on the page, so I left it as-is.

EDIT: I seriously overhauled this project, made an object factory to create new graphics and updated the code for the page. This solution requires almost no HTML or CSS, has a bit more javascript code, but will make it much easier to implement dynamic graphics on the page/functional addition of new elements. http://jsfiddle.net/RnCWN/9/

The javascript solution I came up here with uses real-time updating percentages to set the width and left attributes of the percentage based block, as well as initializing the static height and bottom attributes.

With this revision, you can use the method PercentageBasedGraphic to create a floating box on your page. Here's an example:

PercentageBasedGraphic(25, 10, 4, 30, "block1");

This function will add a div with an id = "block1" attribute, with corresponding width, height, left, and bottom values (all in percentages). It also returns an object which contains all of the information needed to resize and reposition the div that was just created. You can easily expand upon this function by adding different classes to each div. Anyway, how do we finally make use of our returned object?

addGraphic(graphicArr, PercentageBasedGraphic(25, 10, 4, 30, "block1"));

The addGraphic function adds each new floating box to an array. Later, we iterate through this array upon window resize to reposition all of the floating boxes we defined.

I will be honest with you, the Super Mario graphics made this a lot of fun to work on.

like image 141
Joey Avatar answered Sep 27 '22 20:09

Joey