Here's an example of a CSS hyperlink animation from this article:
a {
position: relative;
color: #000;
text-decoration: none;
}
a:hover {
color: #F00;
}
a:before {
content: "";
position: absolute;
width: 100%;
height: 2px;
bottom: 0;
left: 0;
background-color: #F00;
visibility: hidden;
-webkit-transform: scaleX(0);
transform: scaleX(0);
-webkit-transition: all 0.3s ease-in-out 0s;
transition: all 0.3s ease-in-out 0s;
}
a:hover:before {
visibility: visible;
-webkit-transform: scaleX(1);
transform: scaleX(1);
}
<p>As armas e os barões assinalados, que da ocidental praia lusitana, por mares nunca dantes navegados, passaram ainda além da trapobana.</p>
The effect is of the underline progressively appearing (through scaling) form the center to the outline. This is a nice effect accomplished by the :before trick.
However, it completely breaks up when hyperlinks wrap at the margin, and I can't think of any way to fix it...
The problem is that the pseudo-element won't be applied over multiple lines. One workround could be to prevent those line-breaks of the link content.
To achieve this simply add display: inline-block to the a tag
a {
position: relative;
color: #000;
text-decoration: none;
display: inline-block;
}
a:hover {
color: #F00;
}
a:before {
content: "";
position: absolute;
width: 100%;
height: 2px;
bottom: 0;
left: 0;
background-color: #F00;
visibility: hidden;
-webkit-transform: scaleX(0);
transform: scaleX(0);
-webkit-transition: all 0.3s ease-in-out 0s;
transition: all 0.3s ease-in-out 0s;
}
a:hover:before {
visibility: visible;
-webkit-transform: scaleX(1);
transform: scaleX(1);
}
<p>As armas e os barões assinalados, que da ocidental praia lusitana, por mares nunca dantes navegados, passaram ainda além da trapobana As armas e os barões assinalados, que da.</p>
As the psuedo elements wont take multiple lines. you can use white-space: nowrap; to prevent it from wrapping to the next line and animation will look consistent. Even though nothing works as good as like an underline
a {
position: relative;
color: #000;
text-decoration: none;
white-space: nowrap;
}
a:hover {
color: #F00;
}
a:before {
content: "";
position: absolute;
width: 100%;
height: 2px;
bottom: 0;
left: 0;
background-color: #F00;
visibility: hidden;
-webkit-transform: scaleX(0);
transform: scaleX(0);
-webkit-transition: all 0.3s ease-in-out 0s;
transition: all 0.3s ease-in-out 0s;
}
a:hover:before {
visibility: visible;
-webkit-transform: scaleX(1);
transform: scaleX(1);
}
<p>As armas e os barões assinalados, que da ocidental praia lusitana, por mares nunca dantes navegados, passaram ainda além da trapobana.</p>
Related
Like in the question, I have a code
How to make this effect work on many text lines and not as it is now - the effect appears only in 1 of e.g. 2 text lines (like example)
:root {
--00a3a3: #00a3a3;
}
a {
position: relative;
text-decoration: none; /* For Example */
}
a:before {
content: "";
position: absolute;
width: 100%;
height: 2px;
bottom: 0;
left: 0;
background-color: var(--00a3a3);
visibility: hidden;
-webkit-transform: scaleX(0);
transform: scaleX(0);
-webkit-transition: all 0.3s ease-in-out 0s;
transition: all 0.3s ease-in-out 0s;
}
a:hover:before {
visibility: visible;
-webkit-transform: scaleX(1);
transform: scaleX(1);
}
test
<br>
<br>
<a href="#">test
<br>
test2
</a>
Use background combined with box-decoration-break to have a duplicated effect on each line
:root {
--00a3a3: #00a3a3;
}
a {
text-decoration: none;
background:linear-gradient(var(--00a3a3),var(--00a3a3)) bottom center no-repeat;
background-size:0% 2px;
transition: all 0.3s ease-in-out 0s;
/* Remove the below to see the diffrence */
-webkit-box-decoration-break: clone;
box-decoration-break: clone;
}
a:hover{
background-size:100% 2px;
}
test
<br>
<br>
<a href="#">test
<br>
test2
</a>
Get rid of the ::before. Instead apply a background-image to the <a>.
:root {
--00a3a3: #00a3a3;
}
a {
position: relative;
text-decoration: none; /* For Example */
background-image: linear-gradient(#00a3a3, #00a3a3);
background-position: 50% 100%;
background-repeat: no-repeat;
background-size: 0% 2px;
transition: background-size .3s;
}
a:hover {
background-size: 100% 2px;
}
test
<br>
<br>
<a href="#">test
<br>
test2
</a>
Edit:
The problem is that the :before pseudo-element doesn't know that your <a> is two lines. It's just adding a new block element inside it and taking the shape you give it.
If you know that your links will always be two lines, you might be able to get away with using an :after for the second line, like this:
:root {
--00a3a3: #00a3a3;
}
a {
position: relative;
text-decoration: none;
/* For Example */
}
a:before,
a:after {
content: "";
position: absolute;
width: 100%;
height: 2px;
left: 0;
background-color: var(--00a3a3);
visibility: hidden;
-webkit-transform: scaleX(0);
transform: scaleX(0);
-webkit-transition: all 0.3s ease-in-out 0s;
transition: all 0.3s ease-in-out 0s;
}
a:before {
bottom: 0;
}
a:after {
bottom: 1em;
}
a:hover:before,
a:hover:after {
visibility: visible;
-webkit-transform: scaleX(1);
transform: scaleX(1);
}
test
<br>
<br>
<a href="#">test
<br>
test2
</a>
(But you're probably better off restructuring your code to remove the :before.)
I really want to use this +/- toggle button I found on a codepen https://codepen.io/Inlesco/pen/XXRRmY/
Only issue is that the CSS processor it uses is SCSS, and when I change it there to CSS it stops working
The website I'm coding is in CSS and when I paste the CSS from that codepen in my VS Code editor lights up with errors. Is there any way for me to use this with my normal CSS?
.closed {
.vertical {
transition: all 0.5s ease-in-out;
transform: rotate(-90deg);
}
.horizontal {
transition: all 0.5s ease-in-out;
transform: rotate(-90deg);
opacity: 1;
}
}
.opened {
opacity: 1;
.vertical {
transition: all 0.5s ease-in-out;
transform: rotate(90deg);
}
.horizontal {
transition: all 0.5s ease-in-out;
transform: rotate(90deg);
opacity: 0;
}
}
.circle-plus {
height: 4em;
width: 4em;
font-size: 1em;
opacity: .7;
}
.circle-plus .circle {
position: relative;
width: 2.55em;
height: 2.5em;
border-radius: 100%;
border: solid .5em #DFDAD7;
}
.circle-plus .circle .horizontal {
position: absolute;
background-color: red;
width: 30px;
height: 5px;
left: 50%;
margin-left: -15px;
top: 50%;
margin-top: -2.5px;
}
.circle-plus .circle .vertical {
position: absolute;
background-color: red;
width: 5px;
height: 30px;
left: 50%;
margin-left: -2.5px;
top: 50%;
margin-top: -15px;
}
Thanks!
You can manually convert sass into css, or use an online compiler like I did
Result
.closed .vertical {
transition: all 0.5s ease-in-out;
transform: rotate(-90deg);
}
.closed .horizontal {
transition: all 0.5s ease-in-out;
transform: rotate(-90deg);
opacity: 1;
}
.opened {
opacity: 1;
}
.opened .vertical {
transition: all 0.5s ease-in-out;
transform: rotate(90deg);
}
.opened .horizontal {
transition: all 0.5s ease-in-out;
transform: rotate(90deg);
opacity: 0;
}
.circle-plus {
height: 4em;
width: 4em;
font-size: 1em;
opacity: 0.7;
}
.circle-plus .circle {
position: relative;
width: 2.55em;
height: 2.5em;
border-radius: 100%;
border: solid 0.5em #DFDAD7;
}
.circle-plus .circle .horizontal {
position: absolute;
background-color: red;
width: 30px;
height: 5px;
left: 50%;
margin-left: -15px;
top: 50%;
margin-top: -2.5px;
}
.circle-plus .circle .vertical {
position: absolute;
background-color: red;
width: 5px;
height: 30px;
left: 50%;
margin-left: -2.5px;
top: 50%;
margin-top: -15px;
}
You can also setup a preprocessor that compiles scss to css using bundlers, but that's only if your website gets bigger and you feel the need to organize your styles.
Like in the answer from Min Lee, you can simply convert SCSS to CSS. However, it's worth understanding the difference because it's not very significant and simple to do yourself.
All you need to do is remove the nested rules that aren't supported by CSS.
Change this SCSS:
.closed {
.vertical {
transition: all 0.5s ease-in-out;
transform: rotate(-90deg);
}
.horizontal {
transition: all 0.5s ease-in-out;
transform: rotate(-90deg);
opacity: 1;
}
}
.opened {
opacity: 1;
.vertical {
transition: all 0.5s ease-in-out;
transform: rotate(90deg);
}
.horizontal {
transition: all 0.5s ease-in-out;
transform: rotate(90deg);
opacity: 0;
}
}
To this CSS:
.closed .vertical {
transition: all 0.5s ease-in-out;
transform: rotate(-90deg);
}
.closed .horizontal {
transition: all 0.5s ease-in-out;
transform: rotate(-90deg);
opacity: 1;
}
.opened {
opacity: 1;
}
.opened .vertical {
transition: all 0.5s ease-in-out;
transform: rotate(90deg);
}
.opened .horizontal {
transition: all 0.5s ease-in-out;
transform: rotate(90deg);
opacity: 0;
}
I am having a problem getting a underline bar to animate under a text link. You can see a working example here: http://tobiasahlin.com/blog/css-trick-animating-link-underlines/
The animation works fine in all browsers except for Safari 5.1.7. What am I doing wrong? Here is my code snippet:
EDIT: Sorry about that, I added the html and more of the CSS rules. I hope that helps.
.infiniteNav{
width: 100%;
height: 56px;
background-color: #9e0707;
background: linear-gradient(#c71e1e, #800909);
background: -webkit-linear-gradient(#c71e1e, #800909);
position: absolute;
top: 271px;
z-index: -2;
}
nav{
width: 955px;
height: 56px;
float: left;
text-align: center;
display: block;
background-color: #9e0707;
background: linear-gradient( #c71e1e, #800909);
background: -webkit-linear-gradient(#c71e1e, #800909);
}
nav a{
position: relative;
font-size: 25px;
font-family: arial;
color: #e0e0e0;
text-decoration: none;
font-weight: bold;
margin: 0px 15px;
line-height: 55px;
}
/********************************************************************************************************
This is the animated underline bar. *
********************************************************************************************************/
nav a:before{
content: "";
position: absolute;
width: 100%;
height: 2px;
bottom: 0;
left: 0;
background-color: #e0e0e0;
visibility: hidden;
-webkit-transform: scaleX(0);
transform: scaleX(0);
/*-webkit-transition: all 0.3s ease-in-out 0s;*/
-webkit-transition-property: all;
-webkit-transition-duration: 0.3s;
-webkit-transition-timing-function: ease-in-out;
-webkit-transition-delay: 0s;
transition: all 0.3s ease-in-out 0s;
}
nav a:hover:before{
visibility: visible;
-webkit-transform: scaleX(1);
transform: scaleX(1);
color: #e0e0e0;
}
nav a:active{
color: #e0e0e0;
}
<nav>
Home
Shop
Sales
Catalog
Events
Contact
About us
Partners
</nav>
So i have seen this button design that i really like https://codepen.io/lukemeyrick/pen/apZOWm
$thick : 3px;
$pad : 0.7em;
$extra : calc(#{$pad} * 1.2);
$color : #f26522;
body {
background: #2d2d2d;
}
a {
position: fixed;
cursor: pointer;
top: 50vh;
left: 50%;
color: white;
transform: translate3d(-50%,-50%,0);
padding: $pad $extra;
display: inline-block;
border: $thick solid transparent;
position: relative;
font-size: 1.5em;
letter-spacing: 0.07em;
.text {
// padding: 0 0.3em;
font-family: proxima-nova;
transform: translate3d(0,$pad,0);
display: block;
transition: transform 0.4s cubic-bezier(.2,0,0,1) 0.4s;
}
&:after {
position: absolute;
content: '';
bottom: -$thick;
left: $extra;
right: $extra;
height: $thick;
background: $color;
z-index: -1;
transition:
transform 0.8s cubic-bezier(1,0,.37,1) 0.2s,
right 0.2s cubic-bezier(.04,.48,0,1) 0.6s,
left 0.4s cubic-bezier(.04,.48,0,1) 0.6s;
transform-origin: left;
}
}
.line {
position: absolute;
background: $color;
&.-right,
&.-left {
width: $thick;
bottom: -$thick;
top: -$thick;
transform: scale3d(1,0,1);
}
&.-top,
&.-bottom {
height: $thick;
left: -$thick;
right: -$thick;
transform: scale3d(0,1,1);
}
&.-right {
right: -$thick;
transition: transform 0.1s cubic-bezier(1,0,.65,1.01) 0.23s;
transform-origin: top;
}
&.-top {
top: -$thick;
transition: transform 0.08s linear 0.43s;
transform-origin: left;
}
&.-left {
left: -$thick;
transition: transform 0.08s linear 0.51s;
transform-origin: bottom;
}
&.-bottom {
bottom: -$thick;
transition: transform 0.3s cubic-bezier(1,0,.65,1.01);
transform-origin: right;
}
}
a:hover,
a:active {
.text {
transform: translate3d(0,0,0);
transition: transform 0.6s cubic-bezier(.2,0,0,1) 0.4s;
}
&:after {
transform: scale3d(0,1,1);
right: -$thick;
left: -$thick;
transform-origin: right;
transition:
transform 0.2s cubic-bezier(1,0,.65,1.01) 0.17s,
right 0.2s cubic-bezier(1,0,.65,1.01),
left 0s 0.3s;
}
.line {
transform: scale3d(1,1,1);
&.-right {
transition: transform 0.1s cubic-bezier(1,0,.65,1.01) 0.2s;
transform-origin: bottom;
}
&.-top {
transition: transform 0.08s linear 0.4s;
transform-origin: right;
}
&.-left {
transition: transform 0.08s linear 0.48s;
transform-origin: top;
}
&.-bottom {
transition: transform 0.5s cubic-bezier(0,.53,.29,1) 0.56s;
transform-origin: left;
}
}
}
and would like to use it on my WordPress website of http://hcldesign.co.uk/ in stead of the current main navigation menu.
Now this is SCSS and I am not if and how i would be able to use this on my site.
Is it possible to add this button to my nav menu and how could i do this?
Is it possible to convert the SCSS to CSS? Or use SCSS in WordPress.
Thanks,
Harvey
Yes sure, this should be possible, I don´t see why not
If you want to convert it quickly you can use a tool like:
SCSS to CSS
I would like both to behave like webkit, but for some reason in webkit works as I expected but -moz- does the animation when mouseout the .porftolio item,
Any idea why?
CSS:
.portfolio-item {
float: left;
width: 300px;
height: 300px;
margin: 0.5%;
position: relative;
text-align: center;
background: orange;
overflow: hidden;
-webkit-transition: 0.4s all ease;
-moz-transition: 0.4s all ease;
transition: 0.4s all ease;
}
.portfolio-item a:hover:after {
content: " ";
position: absolute;
left: 0;
right: 0;
width: 100%;
height: 100%;
background: linear-gradient(rgba(255, 255, 255, 0.4), transparent 100%);
}
.portfolio-item h4, .portfolio-item img {
-webkit-transition: 0.4s all ease;
-moz-transition: 0.4s all ease;
transition: 0.4s all ease;
}
.portfolio-item img {
width: 100%;
hegight: 100%;
position: absolute;
top: 0;
left: 0;
}
.portfolio-item:before {
content: '';
display: -moz-inline-stack;
display: inline-block;
vertical-align: middle;
*vertical-align: auto;
zoom: 1;
*display: inline;
height: 100%;
vertical-align: middle;
}
.portfolio-item h4 {
opacity: 0;
color: white;
font-size: 30px;
vertical-align: middle;
/*#include transform(scale(.5));*/
display: -moz-inline-stack;
display: inline-block;
vertical-align: middle;
*vertical-align: auto;
zoom: 1;
*display: inline;
/* sino en safari no va */
width: 200px;
font-weight: bold;
text-transform: uppercase;
-webkit-transform: translateX(-2px);
-moz-transform: translateX(-2px);
-ms-transform: translateX(-2px);
transform: translateX(-2px);
}
.portfolio-item:hover {
z-index: 9;
}
.portfolio-item:hover img {
opacity: 0;
-webkit-transform: scale(1.07);
-moz-transform: scale(1.07);
-ms-transform: scale(1.07);
transform: scale(1.07);
}
.portfolio-item:hover h4 {
-webkit-transform: translateX(3px);
-moz-transform: translateX(3px);
-ms-transform: translateX(3px);
transform: translateX(3px);
/*-webkit-animation-duration: 0.4s;
-webkit-transform-origin:50% 50%;
-webkit-animation-timing-function: linear;
-moz-animation-duration: 0.4s;
-moz-transform-origin:50% 50%;
-moz-animation-timing-function: linear;
-webkit-animation-name: shake;
-moz-animation-name: shake;
-o-animation-name: shake;
animation-name: shake;*/
opacity: 1;
}
HTML:
<ul><li class="portfolio-item" style="background-color: #6220E5;">
<a href="#">
<img src="http://dummyimage.com/300x300/dddddd/cccccc" alt="camper" />
<h4>Text goes here</h4>
</a>
</li></ul>
Test:
http://jsfiddle.net/kuX39/
-EDIT-
Funny thing is that I noticed that if instead of applying it to :hover i apply it to .hover and toggle the class then the animations works the same... :S
The problem comes from this rule:
.portfolio-item a:hover:after {
content: " ";
position: absolute;
left: 0;
right: 0;
width: 100%;
height: 100%;
background: linear-gradient(rgba(255, 255, 255, 0.4), transparent 100%);
}
where you define all the after pseudoelement only in the hover state. If the a element is not hovered, the pseudo element is undefined, and can take whatever value the browser decides.
If you set the same on the un-hovered element, it works fine.
.portfolio-item a:after {
content: " ";
position: absolute;
left: 0;
right: 0;
width: 100%;
height: 100%;
background: linear-gradient(rgba(255, 255, 255, 0.4), transparent 100%);
}
updated demo
By the way, my firefox version is using transition and not moz-transition