Flickering Text Problem using CSS Padding Hover Transition - css

I'm not even sure if this is possible!
I'm trying to animate the padding amount around a centered text link. When you click on the text link, the padding is changed from 20% to 100% - this bit works :)
The text is centered using CSS
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
I'm using transition property to animate the padding bit
transition-property: padding;
transition-duration: .5s;
transition-timing-function: ease-in-out;
Apologies if the code is a little clunky - here's the full code I'm using here:
#homePanel {
width: 300px;
height: 300px;
position: relative;
overflow: hidden;
}
#homePanel img {
width: 100%;
filter: grayscale(1%);
transition-property: opacity;
transition-duration: .4s;
transition-timing-function: ease-in-out;
height: auto;
}
#panelLink h3 a {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-weight: bold;
text-transform: uppercase;
text-align: center;
letter-spacing: 2px;
color: #ffffff;
background-color: rgba(0, 0, 0, 0.6);
padding: 20%;
transition-property: padding;
transition-duration: .5s;
transition-timing-function: ease-in-out;
}
#panelLink h3 a {
color: #fff;
text-decoration: none;
}
#panelLink h3 a:hover {
color: #fff;
padding: 100%;
}
<div id="homePanel">
<div id="panelLink">
<img src="https://www.landscapia.co.uk/wp-content/uploads/2022/03/landscapia-design.jpg" alt="Landscapia Design" width="600" height="600" class="img-responsive" />
<h3>Design</h3>
</div>
</div>
The problem I'm having is the text link is wobbling / flickering when I hover the link. I'm guessing this is because the CSS is trying to also re-center the text to adjust for the extra padding, which is causing the flicker on the hover.
I've also included a link to CodePen showing the code in action - https://codepen.io/rolandxp30/pen/oNqZoom
I can't think of any other way of doing this? - is there a way of stabilising or centering the text or another way of creating the same animation effect?
Thanks in advance, kind regards
Brian

I'd use an absolute positioned pseudo element on the link for the background, and then simply apply a transform: scale(...) on hover.
what is an absolute positioned pseudo element?
A pseudo element, that is absolutely positioned ;-)
Positioning it at top/right/bottom/left 0, makes it take the dimensions of the parent. And on hover, it simply gets scaled up. I used a factor of 3 here, that appears to be sufficient. You don't want to go too high here, otherwise there will be a noticeable delay before you see the it shrink again, when you un-hover the element.
#homePanel {
width: 300px;
height: 300px;
position: relative;
overflow: hidden;
}
#homePanel img {
width: 100%;
filter: grayscale(1%);
transition-property: opacity;
transition-duration: .4s;
transition-timing-function: ease-in-out;
height: auto;
}
#panelLink h3 a {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-weight: bold;
text-transform: uppercase;
text-align: center;
letter-spacing: 2px;
color: #ffffff;
padding: 20%;
}
#panelLink h3 a {
color: #fff;
text-decoration: none;
}
#panelLink h3 a::after {
content: "";
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: -1;
background-color: rgba(0, 0, 0, 0.6);
transition-property: transform;
transition-duration: .5s;
transition-timing-function: ease-in-out;
}
#panelLink h3 a:hover::after {
transform: scale(3);
}
<div id="homePanel">
<div id="panelLink">
<img src="https://www.landscapia.co.uk/wp-content/uploads/2022/03/landscapia-design.jpg" alt="Landscapia Design" width="600" height="600" class="img-responsive" />
<h3>Design</h3>
</div>
</div>

Try this it might works!
I just make a design label outside a because of padding. (Note: Please do additional change based on your requirement if required with anchor tag.)
This is html code.
<div id="homePanel">
<div id="panelLink">
<a href="https://www.google.co.uk/"><img
src="https://www.landscapia.co.uk/wp-
content/uploads/2022/03/landscapia-design.jpg" alt="Landscapia Design"
width="600" height="600" class="img-responsive" /></a>
<h3><span>Design</span></h3>
</div>
This is css code:
#homePanel {
width: 300px;
height: 300px;
position: relative;
overflow:hidden;
}
#homePanel img {
width: 100%;
filter: grayscale(1%);
transition-property: opacity;
transition-duration: .4s;
transition-timing-function: ease-in-out;
height: auto;
}
#panelLink h3 span {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-weight: bold;
text-transform: uppercase;
letter-spacing: 2px;
color: #ffffff;
z-index: 1;
}
#panelLink h3 a {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-weight: bold;
text-transform: uppercase;
letter-spacing: 2px;
color: #ffffff;
background-color: rgba(0, 0, 0, 0.6);
padding: 20%;
transition-property: padding;
transition-duration: .5s;
transition-timing-function: ease-in-out;
}
#panelLink h3 a {
text-decoration: none;
}
#panelLink h3 a:hover {
padding: 100%;
}

Related

Why is the transform property not working

So I know that two transforms don't apply at the same time. But at hover, they can replace each other?! Following is the code for a button I am trying to make, but when I hover, the properties don't seem to work! Also, the down-arrow I am trying to insert in there is also not exactly at the center. So due to which I have to use padding to center it!
.btn__bg {
position: absolute;
display: inline-block;
opacity: 0;
top: 75%;
left: 50%;
transform: translate(-50%, -50%);
height: 60px;
width: 60px;
background-color: #000;
border-radius: 50%;
text-align: center;
animation: fadeInTop 1.2s forwards ease-out 1.5s;
transition: all .2s;
box-shadow: 0 4px 40px rgba(0,0,0,.3);
}
.btn__content {
font-size: 30px;
color: #fff;
font-weight: 100;
text-decoration: none;
line-height: normal;
}
.btn__down--text {
display: inline-block;
vertical-align: middle;
}
.btn__bg:hover {
transform: translate(-50%, -50%) scale(1.5);
}
.btn__bg:hover ~ .btn__down--text {
vertical-align: middle;
}
<div class="header__main--text">
<h1 class="header__heading--primary usr-res">welcome</h1>
<a href="#" class="btn btn__bg btn__content usr-res">
<span class="btn__down--text">&downarrow;</span>
</a>
</div>
Any help would be appreciated!
It's not really clear what you mean: The scaling works (?)
The vertical position of the arrow can be adjusted with a margin-top on the span which contains it.
.btn__bg {
position: absolute;
display: inline-block;
opacity: 1;
top: 75%;
left: 50%;
transform: translate(-50%, -50%);
height: 60px;
width: 60px;
background-color: white;
border-radius: 50%;
text-align: center;
animation: fadeInTop 1.2s forwards ease-out 1.5s;
transition: all .2s;
box-shadow: 0 4px 40px rgba(0,0,0,.3);
}
.btn__content {
font-size: 30px;
color: #000;
font-weight: 100;
text-decoration: none;
line-height: normal;
}
.btn__down--text {
display: inline-block;
margin-top:0.3em;
}
.btn__bg:hover {
transform: translate(-50%, -50%) scale(1.5);
}
.btn__bg:hover ~ .btn__down--text {
vertical-align: middle;
}
<div class="header__main--text">
<h1 class="header__heading--primary usr-res">welcome</h1>
<a href="#" class="btn btn__bg btn__content usr-res">
<span class="btn__down--text">&downarrow;</span>
</a>
</div>

Transform Scale Causing Gaps/Lines

I'm building a website currently and am experiencing issues with transform: scale. I've got a button, and when a user hovers over it, two things happen:
A background "sweeps" in diagonally
The button label colour changes
The button grows slightly
I have got this working, and it looks really nice, but after implementing point 3, I'm seeing a weird gap to the left hand side when the button grows.
Here is my code: click for demo
HTML
Hover
CSS
body {
text-align: center;
padding-top: 10%;
}
.button {
display: inline-block;
text-transform: uppercase;
font-size: 1.1em;
font-weight: 600;
background: transparent;
transition: all ease .25s;
border: 3px solid green;
color: green;
position: relative;
overflow: hidden;
z-index: 2;
font-family: sans-serif;
padding: 20px 35px;
text-decoration: none;
}
.button:before {
content: ' ';
transition: all ease-out .25s;
width: 200%;
height: 100%;
position: absolute;
top: 0;
left: 0;
transform-origin: 0 0;
z-index: -1;
transform: skewX(-45deg) translateX(-100%);
background: green;
}
.button:hover:before {
transform: translateX(0);
}
.button:hover {
color: white;
transform: scale(1.1);
}
And here's a screenshot of the gap I'm seeing. This issue occurs in Chrome and Safari (I haven't tested Firefox or IE as I can't download them at work).
Screenshot of weird gap
It "only" appears in Chrome but not Firefox (edit: worse in Edge: first it's on the left then on bottom...). Not sure if a rounding error or something else is the cause of that gap, but I find that replacing border by a box-shadow improves the rendering.
There's still a gap that can be seen near the end of the transition but finally disappears so I added 2 box-shadows on :hover: the new one is inset and fills the gap between "border/box-shadow" and content box faster.
Codepen: http://codepen.io/PhilippeVay/pen/oYjZzK?editors=0100
body {
text-align: center;
padding-top: 10%;
}
.button {
display: inline-block;
text-transform: uppercase;
font-size: 1.1em;
font-weight: 600;
background: transparent;
transition: all ease .25s;
box-shadow: 0 0 0 3px green; /* replaces border which caused a gap in Chr, not Fx */
color: green;
position: relative;
overflow: hidden;
z-index: 2;
font-family: sans-serif;
padding: 19px 34px;
text-decoration: none;
}
.button:before {
content: ' ';
transition: transform ease-out .25s;
width: 200%;
height: 100%;
position: absolute;
top: 0;
left: 0;
transform-origin: 0 0;
z-index: -1;
transform: skewX(-45deg) translateX(-100%);
background: green;
}
.button:hover:before {
transform: translateX(0);
}
.button:hover {
color: white;
box-shadow: 0 0 0 3px green, inset 0 0 0 1px green; /* improves end of transition in Chrome */
transform: scale(1.1);
}
Hover
EDIT: playing with the size of the transitioned :pseudo
.button:before {
content: ' ';
transition: all ease-out .25s;
width: calc(200% + 6px);
height: calc(100% + 6px);
position: absolute;
top: -3px;
left: -3px;
transform-origin: 0 3px;
z-index: -1;
transform: skewX(-45deg) translateX(-100%);
background: green;
}
to take into account the border but that doesn't change anything because of overflow: hidden.
So here's my third try: by adding a container (or having the A element as a container) and keeping the border on the child element, it makes that gap disappear (overflow is around the border).
Codepen: http://codepen.io/PhilippeVay/pen/ZBbKWd
body {
text-align: center;
padding-top: 10%;
}
a {
display: inline-block;
overflow: hidden;
background: transparent;
transition: all ease .25s;
color: green;
position: relative;
z-index: 2;
font-family: sans-serif;
text-decoration: none;
}
a > span {
display: inline-block;
text-transform: uppercase;
font-size: 1.1em;
font-weight: 600;
border: 3px solid green;
padding: 20px 35px;
}
a:before {
content: ' ';
transition: all ease-out .25s;
width: 200%;
height: 100%;
position: absolute;
top: 0;
left: 0;
transform-origin: 0 0;
z-index: -1;
transform: skewX(-45deg) translateX(-100%);
background: green;
}
a:hover:before {
transform: translateX(0);
}
a:hover {
color: white;
transform: scale(1.1);
}
<span class="bd">Hover</span>
Fx transitions till the end flawlessly... and "corrects" the width by adding 2px on the right. But it's already visible in your jsbin so it's another story (and less annoying I guess as user will have clicked by then imho)

I want .tabcontent to appear from 0 center to full size animated over .3 seconds

Sample of hover effect
I want the hover effect to be animated starting from 0 center out to full size over 0.3s. The effect is what I want ,but the animation isn't working.The page I'm going to build will consist of eight different images (two columns four in each) I want this hover effect to work as you hove hover each image.
#tabbox{
height: 300px;
position: relative;
//border: 2px solid #888;
}
#tabbox img{
cursor: pointer;
display: block;
width: 240px;
height: 240px;
}
.tab {
float: left;
}
.tabcontent{
position: absolute;
padding:10px;
top:0;
width: 0px;
height: 0px;
background:rgba(0, 0, 0, .5);
border:1px solid #fff;
margin:10px;
color:#fff;
display:none;
overflow:hidden;
-webkit-transition: height 0.3s ease-in-out;
-moz-transition: height 0.3s ease-in-out;
-o-transition: height 0.3s ease-in-out;
transition: height 0.3s ease-in-out;
}
.tabcontent:before{
content: "";
position: absolute;
z-index: -1;
top: 0;
left: 0;
right: 0;
bottom: 0;
-webkit-transform: scale(0);
transform: scale(0);
-webkit-transition-property: transform;
transition-property: transform;
-webkit-transition-duration: 0.3s;
transition-duration: 0.3s;
-webkit-transition-timing-function: ease-out;
transition-timing-function: ease-out;
}
.tab:hover > .tabcontent{
display: block;
width: 200px;
height: 200px;
}
.tab:hover:before, .tab:active:before{
-webkit-transform: scale(1);
transform: scale(1);
}
<div id="tabbox">
<div class="tab">
<img src="http://zone1.gingermartinco.netdna-cdn.com/wp-content/uploads/2012/04/Napa-Real-Estate-Realtor.jpg" />
<div class="tabcontent">
<p>Text box to describe the images around when you hover over them, this description will change depending on what image you hover over.</p>
</div><!--tabcontent-->
</div><!--tab-->
</div><!--tabbox-->
Just remove the display: none; from .tabcontent as this property can't be animated, only number properties can be animated.
Fiddle:
https://jsfiddle.net/uxouomoy/
Your fiddle and your question code is not the same.
But taking the code from the fiddle you should put the transition only in .tabcontent style. Use top and left properties to animate from the center position to the left corner position.
See the fiddle
Here's the css it is using:
#tabbox {
height: 300px;
position: relative;
//border: 2px solid #888;
}
#tabbox img {
cursor: pointer;
display: block;
width: 240px;
height: 240px;
}
.tab {
float: left;
}
.tabcontent {
position: absolute;
padding: 10px;
width: 0px;
height: 0px;
background: rgba(0, 0, 0, .5);
border: 1px solid #fff;
margin: 10px;
color: #fff;
display: block;
overflow: hidden;
top: 100px;
left: 100px;
visibility: hidden;
transition-timing-function: ease-in-out;
transition-duration: 0.3s;
transition: width top left;
}
.tab:hover > .tabcontent {
visibility: visible;
width: 200px;
height: 200px;
top: 0px;
left: 0px;
}
<div id="tabbox">
<div class="tab">
<img src="http://zone1.gingermartinco.netdna-cdn.com/wp-content/uploads/2012/04/Napa-Real-Estate-Realtor.jpg" />
<div class="tabcontent">
<p>Text box to describe the images around when you hover over them, this description will change depending on what image you hover over.</p>
</div>
<!--tabcontent-->
</div>
<!--tab-->
</div>
<!--tabbox-->

Shivering text with CSS transitions

I've tried creating a ripple effect on hover over with a button, the only problem I have is that the text shakes/rattles/shivers when I hover over it, I want it to stay still for a smooth transition. Any ideas on how to stop this?
a {
display: block;
position: relative;
width: 300px;
height: 50px;
background: rgba(0, 0, 255, .2);
text-decoration: none;
text-align: center;
overflow: hidden;
margin: 10% auto;
}
p,
span:first-of-type,
span:last-of-type {
position: absolute;
margin: 0;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 0;
height: 0;
border-radius: 50%;
transition: all .3s;
}
span:first-of-type {
transition-delay: .1s;
z-index: 1;
}
span:last-of-type {
transition-delay: .2s;
z-index: 2;
}
span.cta {
color: #33C;
text-transform: uppercase;
font-family: Arial;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 300px;
display: block;
transition: color .3s;
z-index: 3;
}
a:hover p,
a:hover span:first-of-type,
a:hover span:last-of-type {
width: 110%;
height: 660%;
border-radius: 50%;
background: rgba(0, 0, 255, .2);
}
a:hover span:first-of-type,
a:hover span:last-of-type {
width: 100%;
height: 100%;
}
a:hover p span {
color: #FFF;
}
<a href="#">
<p>
<span></span>
<span class="cta">Shop the Trend</span>
<span></span>
</p>
</a>
N.B. It's fine in IE11, it happens in every other browser.
Here you go...Modified HTML[added button text inside div and applied new class "textCta" to it]
<span class="cta"><div class="textCta">Shop the Trend</div></span>
CSS
.textCta {
color:#33C;
text-transform:uppercase;
font-family:Arial;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
width: 300px;
display: block;
transition: color .3s;
z-index: 3;
}
Demo
By deleting the p tags and placing the actual text within a div, I managed to stop the shivering and still keep the background effect the same.
Thanks to Nofi for their help.
<a href="#">
<span></span>
<div class="cta">Shop the Trend</div>
<span></span>
</a>

animating pseudo element when passing to another element

I got a pseudo-element that marks the user's current choice in a navigation bar. It's a small upward triangle, an icon font from Font-Awesome. here's a jsFiddle DEMO of it (you need to stretch the result panel so everything will be lined).
.subnav > ul > li.active > a:after {
position: relative;
text-align: center;
font-family: FontAwesome;
top: 25px;
right: 50%;
content: "\f0de";
color: #c1c1c1;
}
I've added some basic jQuery function that switches the .active class, and I'm wondering if there's a way to animate the transition of the pseudo element so it'll move horizontally to the new position.
I know pseudo-elements transition are a thing, but searching and googling around I couldn't find anything similar to what I'm looking for. Is this even possible?
In this solution I used the :target pseudo class to switch states, but I recommend you stick with the jQuery function that switches the .active class.
FIDDLE
Markup
<div class="page" id="one">page one</div>
<div class="page" id="two">page two</div>
<div class="page" id="three">page three</div>
<div class="top">
<div class="arrow"></div>
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
</div>
CSS
.top
{
background: #eee;
position:relative;
overflow: hidden;
}
.arrow
{
border-bottom: 1px solid #c2c2c2;
height: 50px;
}
.arrow:before
{
content: '';
display: block;
width: 14px;
height: 14px;
border: 1px solid #c2c2c2;
border-radius: 3px;
position:absolute;
bottom:-9px;
left: 30px;
background: #fff;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
-webkit-transition: left, 0.5s;
-moz-transition: left, 0.5s;
-o-transition: left, 0.5s;
transition: left, 0.5s;
}
ul
{
position: absolute;
top: 0;
list-style: none;
padding-left: 20px;
margin-top: 15px;
}
li
{
display: inline-block;
text-decoration: none;
font-size: 18px;
color: #676767;
margin-right: 40px;
}
.page
{
width: 100%;
height: 200px;
position: absolute;
top: 80px;
opacity: 0;
background: yellow;
-webkit-transition: opacity, 0.5s;
-moz-transition: opacity, 0.5s;
-o-transition: opacity, 0.5s;
transition: opacity, 0.5s;
}
.page:target
{
opacity: 1;
}
#two
{
background: pink;
}
#three
{
background: brown;
}
#one:target ~ .top .arrow:before
{
left: 30px;
}
#two:target ~ .top .arrow:before
{
left: 105px;
}
#three:target ~ .top .arrow:before
{
left: 189px;
}

Resources