background-position percentage not working
Solution 1
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()
.
Solution 2
background-position
Initial value 0% 0%
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
So any differences on the size of the background image and the size of the element are welcome and that what makes background positioning work with percentages. Otherwise they don't.
Example:
Consider an image with a size of 500X500 px
;
Using a background-position: 50% 50%;
If your div has a width of 600px
;
your background image will be shifted to the right by
50% * (600px - 500px)
that is 50px
Similarly, if the div
has a height of 700px
your background image will be shifted down by
50% * (700px - 500px)
that is 100px
div{
background-image: url(https://i.imgur.com/gcnJ2Qi.png);
background-repeat: no-repeat;
background-position: 50% 50%;
border: solid grey;
width: 600px;
height:700px;
}
<div></div>
In case the div is narrower than the image
Now you're div element is 300X400 px
,and you want to position your background image the same as before (50px right and 100px down)
You will need to specify a negative background-position: -25% -100%;
Because -25% * (300-500) = 50px
and -100% (400-500) = 100px
div{
background-image: url(https://i.imgur.com/gcnJ2Qi.png);
background-repeat: no-repeat;
background-position: -25% -100%;
border: solid grey;
width: 300px;
height:400px;
}
<div></div>
In the case where both div and image have the same size:
Any percentage you specify at background-position
would be multiplied by zero.
And the image will be always aligned with the top left corner of the div. To fix that make the image smaller or bigger by resetting background-size:80% or 120%;
div{
background-image: url(https://i.imgur.com/gcnJ2Qi.png);
background-repeat: no-repeat;
background-position: 50% 100%;
border: solid grey;
width: 500px;
height:500px;
background-size:80%;
}
<div></div>
Related videos on Youtube
Jamie Barker
Updated on June 04, 2022Comments
-
Jamie Barker almost 2 years
Everywhere I read says this should be working fine, but for some reason it's not.
This was to fix someone else's issue so fixing it doesn't matter to me, I just want to know why. The problem is on
.br .bg-image
. I know I'm trying to usecalc()
but using a simplebackground-position: 50%
doesn't work either.http://jsfiddle.net/uLaa9fnu/2/
html { height: 100%; width: 100%; } body { margin: 0px; height: 100%; width: 100%; overflow: hidden; } .bg-image { height: 600px; width: 800px; background-image: url('http://media1.santabanta.com/full1/Outdoors/Landscapes/landscapes-267a.jpg'); background-size: 100%; background-repeat: no-repeat; } .relative { position: relative; } .containeroverlay { background-color: rgba(0, 0, 0, 0.6); height: 100%; width: 100%; } .framesizer { height: 340px; width: 300px; overflow: hidden; position: absolute; } .frame { background-image: url('http://i.imgur.com/4AcIXsD.png'); background-repeat: no-repeat; background-size: 100%; height: 340px; width: 300px; } .tl { top: 30px; left: 30px; } .tl .bg-image { background-position: right 30px bottom 30px; } .br { top: calc(100% - 340px - 30px); /* Height of frame, plus 30px spacing */ left: calc(100% - 300px - 30px); /* Width of frame, plus 30px spacing */ } .br .bg-image { background-position: right calc(800px - 300px - 30px) bottom calc(600px - 340px - 30px); /* Background Position doesn't like percentages for some reason */ }
<div class="bg-image"> <div class="containeroverlay relative"> <div class="framesizer tl"> <div class="bg-image"> <div class="frame"></div> </div> </div> <div class="framesizer br"> <div class="bg-image"> <div class="frame"></div> </div> </div> </div> </div>
-
Jamie Barker almost 9 yearsI understand now what is causing it (+1), however now I wonder why browsers are set to behave like this... Any ideas?
-
Sander Koedood almost 9 yearsAfter looking at it some more, I think I now finally have it all figured. Perhaps you can see if you understand my explanation.
-
Loretta about 3 yearsI've been trying to find a solution for hours. Thank you