background-position percentage not working [duplicate]
Asked Answered
I

3

17

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 use calc() but using a simple background-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>
Irritant answered 8/7, 2015 at 12:7 Comment(3)
Just so I make this clear, you need to center the image on the frame on the bottom right?Algo
What should be happening, what is wrong?Lintwhite
@Lintwhite The bottom right frame should show the part of the image that it is hovering over in the background. In the code above it is working, however it stops working when you replace calc(800px - 300px - 30px) with calc(100% - 300px - 30px) on background-position, even though the width of the image is 800pxIrritant
A
25

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().

Antho answered 8/7, 2015 at 12:28 Comment(3)
I understand now what is causing it (+1), however now I wonder why browsers are set to behave like this... Any ideas?Irritant
After looking at it some more, I think I now finally have it all figured. Perhaps you can see if you understand my explanation.Antho
I've been trying to find a solution for hours. Thank youHorribly
K
4

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>

The docs

Kendo answered 16/11, 2017 at 12:35 Comment(0)
S
0

GEspinha is somewhat right. This example works as you might expect:

.br .bg-image {
  background: url('http://media1.santabanta.com/full') 50% 50%;
}

while having this - it wont work.

.br .bg-image {
    background-position:50% 50%;
}

http://jsfiddle.net/gtj5p0px/ (if this is your expeted output for the bottom right frame)

Selina answered 8/7, 2015 at 12:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.