Background-Position Percentage Not Working

background-position percentage not working

Solving the problem

After some fiddling I've found what is causing the issue. background-position stops working when the background is as big (or bigger) as the frame it contains.
This is also why dognose's solution works. It removes the background-size.

As proof, I've changed the CSS of the .br-frame and .br .bg-image to the following:

.br {
top:calc(100% - 340px - 30px);
left:calc(100% - 300px - 30px);
}
.br .bg-image {
background-position: calc(100% + 30px) calc(100% + 30px);
/* 100% puts it bottom right, + 30px offset from .br */
background-position: right -30px bottom -30px;
/* or simply use this */
height: 100%;
width: 100%;
background-size: 800px 600px;
}

This way the background-size doesn't equal the frame anymore, causing the background-position to work as it is supposed to.

See the fiddle

The why

The reason it doesn't work with percentages, is because the background-position depends on the background-size, literally. Because background-position: 0% 0%; is top left, and background-position: 100% 100%; is bottom right. If the background image is as big as it's containing frame, there is no more difference between 0% and 100%.

Using this theory in combination with calc(), all it does is:

calc(100% - 340px - 30px) place it to the right (100%), which doesn't move it at all, then move it a total of 370px (-340px - 30px) to the left.

In your case it goes to the right, because you prefixed right before your calc().

How to use background-position percentage correctly in this case?

When you use percentages in background-position:

The size of the background positioning area minus size of background image; size refers to the width for horizontal offsets and to the height for vertical offsets

https://developer.mozilla.org/en-US/docs/Web/CSS/background-position

.container {

position: relative;

display: block;

width: 100%;

font-size: 0;

}

.container>div {

display: inline-block;

height: 200px;

background-repeat: no-repeat;

}

.container#example1>div {

width: 50%;

background-size: 200% 100%;

}

.container#example2>div {

width: 33.33%;

background-size: 300% 100%;

}

.container#example3>div {

width: 25%;

background-size: 400% 100%;

}

#example1 #d1 {

background-image: url(http://placehold.it/500x400/333333/000000);

background-position: 0% 0;

}

#example1 #d2 {

background-image: url(http://placehold.it/500x400/666666/000000);

background-position: 100% 0;

}

#example2 #d1 {

background-image: url(http://placehold.it/50x400/333333/000000);

background-position: 0% 0;

}

#example2 #d2 {

background-image: url(http://placehold.it/50x400/666666/000000);

background-position: 50% 0;

}

#example2 #d3 {

background-image: url(http://placehold.it/50x400/999999/000000);

background-position: 100% 0;

}

#example3 #d1 {

background-image: url(http://weknownyourdreamz.com/images/park/park-07.jpg);

background-position: 0% 0;

}

#example3 #d2 {

background-image: url(http://weknownyourdreamz.com/images/park/park-07.jpg);

background-position: 33.33% 0;

}

#example3 #d3 {

background-image: url(http://weknownyourdreamz.com/images/park/park-07.jpg);

background-position: 66.66% 0;

}

#example3 #d4 {

background-image: url(http://weknownyourdreamz.com/images/park/park-07.jpg);

background-position: 100% 0;

}
<div id="example1" class="container">

<div id="d1"></div>

<div id="d2"></div>

</div>

<hr>

<div id="example2" class="container">

<div id="d1"></div>

<div id="d2"></div>

<div id="d3"></div>

</div>

<hr>

<div id="example3" class="container">

<div id="d1"></div>

<div id="d2"></div>

<div id="d3"></div>

<div id="d4"></div>

</div>

CSS background-position ignored when using background-size

Percentage values for background-position have funky behavior with relation to background-size, which I explain in depth, complete with a sliding puzzle analogy, in this answer. Unfortunately, because the background image fits the box exactly due to background-size: 100%, you won't be able to position it using percentage values. From the final paragraph of my answer:

If you want to position a background image whose size is 100% of the background area, you won't be able to use a percentage, since you can't move a tile that fits its frame perfectly (which incidentally would make for either the most boring puzzle or the perfect prank). This applies whether the intrinsic dimensions of the background image match the dimensions of the element, or you explicitly set background-size: 100%. So, to position the image, you will need to use use an absolute value instead (forgoing the sliding-puzzle analogy altogether).

The reason it works with background-size: 50% is because the image is now given space to move around. At the same time, the sliding puzzle analogy now falls flat because the percentage values you've set for background-position are greater than 100%...

Anyway, in your specific example, the absolute values are equal to your element's width and height properties respectively (note: not the actual image dimensions):

div {
background: url(image.png) no-repeat 250px 100px/100%;
height: 100px; /* half height of image */
width: 250px; /* half width of image */
}

Updated fiddle

If you cannot hardcode these values, e.g. if you need this effect to apply across elements of different sizes, then unfortunately you will not be able to use background-position to hide the image.

Use percentage with background position

You can do some calculation in order to convert the % value to pixel if you want to consider the % relative to width of the container (or the width of the initial image or any other value).

You can try this:

function call(value) {

var w = document.getElementById("img").offsetWidth;

var v = (value * w)/100

document.getElementById("img").style.backgroundPositionX = -v + "px";

}
#img {

width: 400px;

height: 50px;

background: url("https://i.stack.imgur.com/fTyE3.png") no-repeat;

background-size: cover;

}

input {

margin-top:50px;

}
<div id="img"></div>

<input type="text" oninput="call(this.value)" >

Background-position negative percentage values

The issue is that the percentage value is not what we (or at least I) thought it was. Or at least it is not calculated using the assumed values.

Is the percentage calculated from the width/height of the containing box? The answer is "No".

According to the W3 documentation:

Percentages refer to size of background positioning area minus size of background image; see text

And from the MDN link that you shared:

Percentages refer to the size of the background positioning area minus size of background image; size refers to the width for horizontal offsets and to the height for vertical offsets


What does this mean?

The background position percentage is calculated relative to the resulting number of:

box size - image size = [number used for the percentage calculations]

In your particular case, the background image is 200 pixels by 200 pixels, and the box has the same size. Then, the percentage is not referred to the 200 pixels of the box but to:

200 - 200 = 0

As the result is 0, whatever number/percentage you multiply by it will result in 0.

firefox background position percentage not working

FF doesn't know about background-position-x, he knows only about background-position. So you can write this like:

#process-section #process-idea.process .image-block {
background-position: -200% 0;
}


Related Topics



Leave a reply



Submit