Why Don't Absolute-Positioned Elements Remain Aligned to Background Image when Browser Widens/Nar?

I put an image on the page to cover 3/4 the browser width (per design). The image is inside a parent <div> with position relative. Also within that div is a container <div class="pins-wrapper"> that I put a few 'pin' elements as <i> elements with display:block; ... here are some snippets:
<map-holder><img src="/map-image.png" alt="Its a map!" />
<div class="pins-wrapper">
<i id="pin1" class="material-icons">place</i>
<i id="pin2" class="material-icons">place</i>
<i id="pin3" class="material-icons">place</i>
</div>
</map-holder>
<map-holder><img src="/map-image.png" alt="Its a map!" />
<div class="pins-wrapper">
<i id="pin1" class="material-icons">place</i>
<i id="pin2" class="material-icons">place</i>
<i id="pin3" class="material-icons">place</i>
</div>
</map-holder>
map-holder, .pins-wrapper i { display:block; }
map-holder { position:absolute; width:75%; right:0px; top:0px; bottom:0px; overflow:hidden; }
map-holder img { height:100%; width:100%; display:block; pointer-events:none; }
.pins-wrapper { position:absolute; top:0px; left:0px; bottom:0px; right:0px; }
map-holder i.material-icons { position:absolute; font-size:64px; transform-origin:center bottom; transform:translate(-50%,-100%); }
#pin1 { top: 25.000%; left:30.000%; }
#pin2 { top: 40.000%; left:75.000%; }
#pin3 { top: 80.000%; left:50.000%; }
map-holder, .pins-wrapper i { display:block; }
map-holder { position:absolute; width:75%; right:0px; top:0px; bottom:0px; overflow:hidden; }
map-holder img { height:100%; width:100%; display:block; pointer-events:none; }
.pins-wrapper { position:absolute; top:0px; left:0px; bottom:0px; right:0px; }
map-holder i.material-icons { position:absolute; font-size:64px; transform-origin:center bottom; transform:translate(-50%,-100%); }
#pin1 { top: 25.000%; left:30.000%; }
#pin2 { top: 40.000%; left:75.000%; }
#pin3 { top: 80.000%; left:50.000%; }
The container for the pins is edge-anchored to the container holding the map image which is full-sized to that container. When the browser width changes, the precision placed pins creep off their target points so they no longer align to the map behind them. The creep is significant (15px) when the browser width changes from, say, 1400px wide to 1600px wide. Those pins should NOT creep at all due to all the anchoring!! What is causing them to malign?? I need those pins to remain stable above their respective targets no matter what width the browser has. Thanks for any help offered!
16 Replies
Jochem
Jochem4mo ago
it's really hard to figure this stuff out without being able to see it in your own browser. Can you share a live version, or ideally a minimal reproduction in codepen or something similar? I don't know if I'll have time today, but it usually helps others help you if there's something to click and poke around in the dev tools with
ProdJuan
ProdJuan4mo ago
here's a pen: https://codepen.io/prodjuan/full/WNWMENO - resize the window larger/smaller width, and you'll see the pins shifting around. I need solid stable anchors for what I'm doing. This isn't working for that. Thanks!
MarkBoots
MarkBoots4mo ago
it is because your icons have a fixed size and are positioned from the top left corner, translate them to the center of the position by adding transform: translate(-50%, -50%) (maybe you want the second value to be -100% so the bottom of the pin lines up to the position you want)
Mannix
Mannix4mo ago
I fell using clamp on the font-size could fix this issue but i'm not sure changing 48px to clamp(16px, 5vw, 64px) seems to work but is not pixel perfect
ProdJuan
ProdJuan4mo ago
what would transform-origin do in this case? I put transform translate on all the icons, adjusted offset for first pin... all 5 pins adjusted, pen saved, should be current now project spec calls for 'large pins' so they are fixed size by design.
MarkBoots
MarkBoots4mo ago
in this case not much as you are only translating. it would be different if you rotate, skew or scale that's okay, the translate works on the size of the element. so if you translate with a percentage, the size doesn't matter
ProdJuan
ProdJuan4mo ago
I added a few more container elements to the pen to better resemble the actual case on my page.
MarkBoots
MarkBoots4mo ago
yea, thats seems okay. maybe it's a bit too much for you now, but if you you want, you can make it yourself a bit easier by using some calculations which make it easier to position the markers https://codepen.io/MarkBoots/pen/OJGQQbE (i didn't use an image as the background, but gradients to create the grid, but you can keep it as you like)
ProdJuan
ProdJuan4mo ago
latest has upper/lower container, grid-item height set by css to scale with browser width. so those pins actually land on/over a map image (an image is an image), so that's the basis for using an image of a grid rather than CSS-constructed lines/boxes. nifty css-block making those boxes though! Mark, If I wanted to use 'right/bottom' as the means to position the pin icons, how would I adjust the transform so that they would be as stable as they are using the left/top in CSS? @MarkBoots I updated the codepen to have the first icon positioned using right/bottom properties and you can see how it creeps around while the others are stable.
MarkBoots
MarkBoots4mo ago
can not see it updated. but if you position it from the right bottom, you'll need to translate it 50% to the right to get it into the middle of that point. the bottom should be good so translate(50%, 0%)
#pin01 { right: 74.5%; bottom: 69%; transform:translate(50%,0%)}
#pin01 { right: 74.5%; bottom: 69%; transform:translate(50%,0%)}
ProdJuan
ProdJuan4mo ago
ok, sorry, just hit save button in codepen for it. (the orange pin is the one that used to be from top left)
MarkBoots
MarkBoots4mo ago
this is kinda what is done the pin is placed with the bottom and right position (blue dot), to get it to the center, translate it half the width
No description
ProdJuan
ProdJuan4mo ago
ok, the orange pin in top left is positioned using bottom/right with the translate(50%,0%). Is it holding stable for you as width changes? at 64px tall, those pin icons .... the bottom tip isn't at the zero line, it's up a few px from the bottom. that might account for some vertical shifting.
MarkBoots
MarkBoots4mo ago
that is because the actual bounding box is a bit larger than the icon itself. don't think there is much you can do about that
No description
MarkBoots
MarkBoots4mo ago
you could try adjusting the line height a bit, something like line-height: 0.8
ProdJuan
ProdJuan4mo ago
well, I was thinking something like transform(-50%,calc(-100% + 4px)) the premise being: try and match the position top/left (bottom/right) to the tip of the pin as close as can be done.