I'm adding some hover animations to a map I'm creating as part of a website (all through CSS), and while it works as intended I'm trying to tinker with the 'top' values so the text itself doesn't move during the transition. Below is a snippet of the code I've got. It's not the whole thing (the whole thing would be 26 of the same thing), but what's here is 1 example that show's what I'm trying to do.
CSS & HTML, No JavaScript (trying to avoid the language):
.Container{ /* Container for Map Elements */
position: relative;
width: 100%;
height: 100%;
font-size: 0.45vw;
font-family: "p22-underground", sans-serif;
font-weight: 600;
font-style: normal;
}
.MBRAnim:hover{ /* Hover animation for Bus Routes in Map Key */
justify-content: center;
cursor: pointer;
color: white; transition: 1s;
background-color: white; padding-top: 0.1815vh; padding-bottom: 0.1815vh; top: calc(top - 0.093vw); transition: 1s;
}
a:link{
color: black;
}
a:visited{
color: black;
}
.Map81{
background-color: #997f53;
position: absolute;
top: 88.3%;
left: 4.4%;
transition-property: top;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Buses Map</title>
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="https://use.typekit.net/job3hev.css">
</head>
<body>
<div class="Container">
<img class="map" src="Test_assets\Map_Rescaled.png" width="100%" height="100%">
<div class="MapBusRoutes"> <!--Extra Container div for organisation purposes-->
<div class="Map81 MBRAnim">
<a href="Bus_81.html">81 - Hounslow Bus Station - Slough Bus Station</a>
</div>
</div>
</div>
</body>
</html>
The transition works as expected which I'm not worried about, but I'd preferrably want to have the top value change so the text stays in the same Y-position. I tried that with the "top: calc(top - 0.093vw);" in the CSS under the MBRAnim:hover class with an added transition property in the "Map81" class, though it's not working for me. I'm pretty sure I have the right sort of idea but probably just have something wrong somewhere, so it'd be nice to quickly get a second pair of eyes to see if I've missed anything.
Interesting one. In your example you are adjusting the top and bottom padding of the button on :hover
, then trying to make a compensating adjustment to the top
in order to keep the text in the same place. In my example I am using a transform: translateY()
to do the job instead, sliding the text up by the same amount as the extra top padding. I have also split the button into two so I can demonstrate what happens both with and without a transition
.
a {
color: inherit;
text-decoration: none;
}
.Container {
position: relative;
font-family: "p22-underground", sans-serif;
font-weight: 600;
font-style: normal;
}
.Container img {
width: 100%;
}
.Map81, .Map82 {
background-color: orange;
position: absolute;
top: 10%;
padding: 0.2em 0.6em;
border-radius: 0.5em;
}
.Map81 {
transition: 0.5s;
left: 10%;
}
.Map82 {
right: 10%;
}
.MBRAnim:hover {
background-color: white;
padding: 0.5em 0.6em 0.5em;
transform: translateY(-0.3em);
}
<link rel="stylesheet" href="https://use.typekit.net/job3hev.css">
<div class="Container">
<img src="https://picsum.photos/1000/300">
<div class="Map81 MBRAnim">
<a href="Bus_81.html">With transition</a>
</div>
<div class="Map82 MBRAnim">
<a href="Bus_81.html">No transition</a>
</div>
</div>
The button on the right does not have a transition. It works perfectly. The padding is adjusted and the text remains in place. (As far as Chrome is concerned, anyway. In Safari the text appears to move by one pixel.)
The button on the left does have a transition. Although the text does end up in the same place after the transition completes, during the transition it wobbles around. On my computer, the effect is more obvious in Safari than in Chrome, but the wobbling is still visible in Chrome if I look closely. I can’t explain the wobbling other than to say that I guess that it’s a quantization effect of the mathematics used by the rendering engines to implement the transition. I don’t know the details of how browsers render text, but perhaps they aim to maximise the perceived sharpness of text by quantizing its position to align with physical pixels on the display?
My recommendation is to use a style like transform: scale(1.02)
on hover rather than adjusting the padding.
a {
color: inherit;
text-decoration: none;
}
.Container {
position: relative;
font-family: "p22-underground", sans-serif;
font-weight: 600;
font-style: normal;
}
.Container img {
width: 100%;
}
.Map81 {
background-color: orange;
position: absolute;
transition: 0.5s;
left: 10%;
top: 10%;
padding: 0.2em 0.6em;
border-radius: 0.5em;
}
.MBRAnim:hover {
background-color: white;
transform: scale(1.02);
}
<link rel="stylesheet" href="https://use.typekit.net/job3hev.css">
<div class="Container">
<img src="https://picsum.photos/1000/300">
<div class="Map81 MBRAnim">
<a href="Bus_81.html">81 - Hounslow Bus Station - Slough Bus Station</a>
</div>
</div>