1

I'm building an advent calendar.. test CodePen here: https://codepen.io/ultrabritain/pen/jOrXYOL?editors=1100

HTML

<div class='doorContainer'>
    <div class='doorOuter'>
      <div class='doors'>
        <div class="door1 door">  
        </div><div class="door2 door">  
        </div>
      </div>
    </div>
</div>

CSS

* { position:relative; margin:0; padding:0; }

html, body {
  height:100%;
  width:100%;
}
.doorContainer { 
  width:100%; 
  height:100%; 
  padding:0; 
  margin:0; 
}
    
.doorOuter {
  padding-bottom:56.25%;
}

.doors {
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  width:100%;
  height:100%;
  background:url(https://www.ultrabritain.com/TWDCCMSv5/EventClient/EventImages/tgd3423wsz_A8djF4Z5dg) no-repeat;
  background-size:contain;
}

.door {
  position:absolute;
  border:1px dashed #fff;
  background:brown url(https://www.ultrabritain.com/TWDCCMSv5/EventClient/EventImages/tgd3423wsz_A8djF4Z5dg);
  background-repeat:no-repeat;
}

.door1 {
  top:5%;
  left:5%;
  width:10%;
  height:20%;
  background-position:5.6% 6.4%;
  background-size:1000%; 
}

.door2 {
  top:15%;
  left:55%;
  width:10%;
  height:25%;
  background-position:61.2% 20.2%;
  background-size:1000%;
}

I'm using a fixed aspect ratio DIV for the calendar with a background image set to background-size:contain to fill the div. The src image is the same aspect ratio as the div.

Doors are absolute-positioned and sized using % units so the calendar is responsive. I want the doors to feature the same background image (I will open them with transform3d so that's why I need to copy across the background).

An example door is positioned at top:5%; left:5%; width:10%; height:20%; background-size:1000%;

I would have expected setting background-position:5% 5% would work but instead after trial and error I've found 5.6% 6.4% is what's needed.

Any idea why these values aren't what I expected? Or is there an easier way to do this?

WindsorAndy
  • 237
  • 1
  • 11

1 Answers1

0

EDIT: the problem seems to be that we cannot get exact accuracy of positioning for all aspect ratios of image versus viewport. The padding-bottom is an approximation - often used to get say 16:9 videos placed OK but in this case we don't have very neat numbers as the basic dimensions of the image (1599x900).

The closest I have been able to get is in this code. Maybe forcing the image to be more 'normal' size might help - but I don't see that being OK for all device aspect ratios.

<style>
* {
  --w: 1599; /* the width of the image */
  --h: 900; /* the height of the image */
  position:relative;
  margin:0;
  padding:0;
}

html, body {
  height:100%;
  width:100%;
}
.doorContainer { 
  width:100%; 
  height:100%; 
  padding:0; 
  margin:0; 
}
    
.doorOuter {
/*  padding-bottom:56.25%; *//* not accurate enough*/
}

.doors {
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  width:100vw;
  height: calc(calc(100vw * var(--h)) / var(--w)); /* this wont be absolutely accurate in most cases */
  background:url(https:/www.ultrabritain.com/TWDCCMSv5/EventClient/EventImages/tgd3423wsz_A8djF4Z5dg) no-repeat;
  background-size:contain;
}

.door {
  position:absolute;
  border:1px dashed #fff;
  background:brown url(https://www.ultrabritain.com/TWDCCMSv5/EventClient/EventImages/tgd3423wsz_A8djF4Z5dg);
  background-repeat:no-repeat;
}

.door1 {
  top:5%;
  left:5%;
  width:10%;
  height:20%;
  background-position:5.6% 6.4%;
  background-size:1000%; 
}

.door2 {
  top:15%;
  left:55%;
  width:10%;
  height:25%;
  background-position:61.2% 20.2%;
  background-size:1000%;
}
</style>
<div class='doorContainer'>
    <div class='doorOuter'>
      <div class='doors'>
        <div class="door1 door">  
        </div><div class="door2 door">  
        </div>
      </div>
    </div>
</div>

................ This was the original answer which did not solve the problem but is left here as a reminder about width calculations/borders etc. I think the need to slightly alter positions arises from the fact that you have a border set (1px width) on some elements - their width will (under default settings) alter the overall width and height of the element.

Luckily we can get round this in CSS if we set:

* {
  box-sizing: border-box;
}

Any padding or border will now be included in the width of an element.

I'm not sure whether you need to set any settings that the browser user agent might introduce, but to be on the safe side it's worth putting this setting at the top of your CSS.

   * {
     margin: 0;
     padding: 0;
   }
A Haworth
  • 30,908
  • 4
  • 11
  • 14
  • Thanks for your answer! I did set padding+margin to be 0 but forgot the box-sizing property - I use a standard reset css usually and you get out of the habit of copying over the essentials when using something like codepen! It doesn't seem to have changed the layout in this case though – WindsorAndy Nov 12 '20 at 17:50
  • That's definitely weird - back to the drawing board (I like the idea of an Advent Calendar BTW). – A Haworth Nov 12 '20 at 18:06
  • There's something odd about when the background fills the containing element. I do not understand this [link]https://stackoverflow.com/questions/31292187/background-position-percentage-not-working (yet...) but is there something in there that is relevant as you have backgrounds both filling and more than filling their elements? – A Haworth Nov 12 '20 at 18:42
  • Third attempt - the padding at the bottom cannot be exactly accurate - even if we go to more decimal places - and that causes a problem with getting aspect ratio exactly correct. – A Haworth Nov 12 '20 at 20:48
  • The positions in the SO link are all nice round numbers whereas I've got random values! I've moved the second door in the pen and I can't see any relation between the expected offset values and the ones that are needed. Interestingly it looks ok in FF, Chrome and even Edge! If the padding were out I'd have thought as the window is resized, things would break but it remains solid – WindsorAndy Nov 12 '20 at 21:00
  • I'm getting it to do the calculations even as we speak - but it's not accurate to pixel - may fool the user though. – A Haworth Nov 12 '20 at 21:05
  • Have updated the answer with calculation of height. The SO snippet system would not show the background for some reason so as an interim measure I have put it up on [link]http://ahweb.org.uk/advent-calendar.html and will leave it there for a few days. There must be a better way of doing this, but I can't find it! – A Haworth Nov 12 '20 at 21:22
  • Thanks for the time you've out into this! I'm satisfied that a lot of my confusion is down tomy incomplete understanding of how background-position works with %ages and this has helped sort that out. For this application I don't need pixel-perfect so I can get away with near enough. I've updated my pen with opening doors with a solid inside ocver to the doors.. will do the job I think – WindsorAndy Nov 13 '20 at 11:27
  • Yes, I don't think users will notice - especially since your image is 'real' rather than say geometrical/lines. Thanks for giving me the idea of an Advent Calendar. – A Haworth Nov 13 '20 at 12:44