Hover link border animation - html

I would like to know how to animate the link when I hover on it. I want the top border to move down and the bottom border to move up. The borders should fade away, when the animation ends. When I hover on the link, the borders should appear and show the animation.
HTML:
<ul>
<li class="active">Home</li>
<li>About Me</li>
<li>My Passion</li>
</ul>
CSS:
ul li a {
border-bottom: 3px transparent solid;
border-top: 3px transparent solid;
}
ul li a::before {
position: absolute;
left: 0;
top: 0;
visibility: hidden;
-moz-transition: 0.3s;
-o-transition: 0.3s;
-webkit-transition: 0.3s;
transition: 0.3s;
}
ul li a::after {
position: absolute;
left: 0;
top: 100%;
visibility: hidden;
-moz-transition: 0.3s;
-o-transition: 0.3s;
-webkit-transition: 0.3s;
transition: 0.3s;
}
ul li a:hover {
color: blue;
}
ul li a:hover::before {
visibility: visible;
top: 100%;
background: blue;
}
ul li a:hover::after {
visibility: visible;
top: 0;
background: blue;
}
Expected result:

I've re-created the example in your GIF.
For the text hover effect, make sure to use transition to ease the effect, e.g.:
a {
color: white;
text-decoration: none;
transition: 800ms ease color;
display: block;
}
a:hover {
color: gold;
}
I'm displaying the a tag as block to make sure it covers the whole li elements when hovered.
When using CSS pseudo elements always set a content property (content: '' is you want to style it):
li::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 5px;
background: gold;
opacity: 0;
}
Instead of using a border, I'm animating the pseudo before en after elements on hover. You can do this by using CSS keyframes.
li:hover::before {
opacity: 1;
animation: flyDown 300ms ease forwards;
}
li:hover::after {
opacity: 1;
animation: flyUp 300ms ease forwards;
}
#keyframes flyDown {
from {
transform: translateY(0px)
}
to {
transform: translateY(90px)
}
}
#keyframes flyUp {
from {
transform: translateY(00px)
}
to {
transform: translateY(-90px)
}
}
Please find jsfiddle here: https://jsfiddle.net/sanderdebr/fn4pgwv6/30/

---html---
<span class="a-border" onclick="menuclick(this)">ABOUT US</span>
<span class="a-border" onclick="menuclick(this)">CREATERS</span>
<span class="a-border" onclick="menuclick(this)">NEWS</span>
<span class="a-border" onclick="menuclick(this)">CONTACT</span>
---css---
a {
text-decoration: none;
}
a:hover {
cursor: pointer;
}
.a-border {
display: inline-block;
position: relative;
color: white;
padding: 0.5rem 0.25rem;
margin: 0 1.5rem;
overflow: hidden;
}
.a-border::after {
content: "";
display: block;
position: absolute;
bottom: -8px;
left: -3%;
width: 106%
border-top: 2px solid white;
transform: scale(0, 1);
transform-origin: 0% 100%;
transition: transform 0.4s;
}
a:hover .a-border::after {
transform:scale(1, 1);
}
a.focused .a-border::after {
transform: none;
}
---js---
function menuclick(underline) {
var focused = document.getElementsByClassName("focused");
var i;
for (i = 0; i < focused.length; i++) {
var under = focused[i];
if (under.classList.contains('focused')) {
under.classList.remove('focused');
}
}
if (!underline.parentElement.classList.contains('focused')) {
underline.parentElement.classList.add('focused');
}
}

Related

How can I trigger multiple hover actions on links when hovering over a div?

Im trying to trigger multiple hover effects when hovering over my main div. I can´t figure out how make the line animate on all three links at the same time, and whether this can be done in only css or if i have to use javascript, and im not finding the right solution to previous posts. Here is the code:
.right-project-headline h2 a {
text-decoration: none;
color: black;
position: relative;
}
.right-project-headline h2 a::before, .right-project-headline h2 a::after {
content: '';
background: black;
position: absolute;
top: 55%;
height: 3px;
width: 0;
}
.right-project-headline h2 a::before {
left: 0;
}
.right-project-headline h2 a::after {
right: 0;
transition: width 500ms ease;
}
.right-project-headline h2 a:hover::before {
width: 100%;
transition: width 500ms ease;
}
.right-project-headline h2 a:hover::after {
width: 100%;
background: transparent;
transition: 0;
}
<div class="right-project-headline">
<h2>The</h2>
<h2>Industrial</h2>
<h2>Revolutions</h2>
</div>
I would simplify your code like below and apply hover effect on the parent container
.right-project-headline h2 a {
text-decoration: none;
color: black;
background: linear-gradient(black, black) no-repeat;
background-size: 0% 4px; /*left:0 top:55%*/
background-position: 0% 55%; /*left:0 top:55%*/
transition: background-size 0.5s, background-position 0s 0.5s;
}
.right-project-headline:hover h2 a {
background-size: 100% 4px; /*width:100% height:4px*/
background-position: 100% 55%; /*right:0 top:55%*/
}
<div class="right-project-headline">
<h2>The</h2>
<h2>Industrial</h2>
<h2>Revolutions</h2>
</div>
Here is another syntax for background-position (more intuitive):
.right-project-headline h2 a {
text-decoration: none;
color: black;
background: linear-gradient(black, black) no-repeat;
background-size: 0% 4px;
background-position: left 0 top 55%;
transition: background-size 0.5s, background-position 0s 0.5s;
}
.right-project-headline:hover h2 a {
background-size: 100% 4px;
background-position: right 0 top 55%;
}
<div class="right-project-headline">
<h2>The</h2>
<h2>Industrial</h2>
<h2>Revolutions</h2>
</div>
Another one with the shorthand version and less of code:
.right-project-headline h2 a {
text-decoration: none;
color: black;
background: linear-gradient(black, black) var(--p,0%) 55%/var(--p,0%) 4px no-repeat;
transition: background-size 0.5s, background-position 0s 0.5s;
}
.right-project-headline:hover h2 a {
--p:100%;
}
<div class="right-project-headline">
<h2>The</h2>
<h2>Industrial</h2>
<h2>Revolutions</h2>
</div>
You have to add :hover to your div in CSS and not to your a elements.
This is selector for a in div
div a
This is selector for hovered a in div
div a:hover
And this is selector for a in hovered div
div:hover a
So this should do the trick
.right-project-headline h2 a {
text-decoration: none;
color: black;
position: relative;
}
.right-project-headline h2 a::before, .right-project-headline h2 a::after {
content: '';
background: black;
position: absolute;
top: 55%;
height: 3px;
width: 0;
}
.right-project-headline h2 a::before {
left: 0;
}
.right-project-headline h2 a::after {
right: 0;
transition: width 500ms ease;
}
.right-project-headline:hover h2 a::before {
width: 100%;
transition: width 500ms ease;
}
.right-project-headline:hover h2 a::after {
width: 100%;
background: transparent;
transition: 0;
}
You need to catch the hover event on the element with class .right-project-headline and then apply the style to the <a> elements inside it, like this:
.right-project-headline:hover a::before {
width: 100%;
transition: width 500ms ease;
}
.right-project-headline:hover a::after {
width: 100%;
background: transparent;
transition: 0;
}
Complete Example:
.right-project-headline {
border: 1px solid red;
}
.right-project-headline a {
text-decoration: none;
color: black;
position: relative;
}
.right-project-headline a::before, .right-project-headline a::after {
content: '';
background: black;
position: absolute;
top: 55%;
height: 3px;
width: 0;
}
.right-project-headline a::before {
left: 0;
}
.right-project-headline a::after {
right: 0;
transition: width 500ms ease;
}
.right-project-headline:hover a::before {
width: 100%;
transition: width 500ms ease;
}
.right-project-headline:hover a::after {
width: 100%;
background: transparent;
transition: 0;
}
<div class="right-project-headline">
<h2>The</h2>
<h2>Industrial</h2>
<h2>Revolutions</h2>
</div>

How to keep active menu item underlined?

I'm really new to HTML and CSS. I have a navbar which underlines the menu item you hover with a fade in, fade out-effect from the middle,
but how can I keep an active menu item underlined with the same style?
I'm also using Typo3 / Fluid which creates me the html code and assigns the "active" class to the active menu item.
This is how it looks like so far: https://jsfiddle.net/wr5w09r0/
css
div#top_nav{
text-align: center;
}
div#top_nav li{
display: inline;
padding: 15px;
}
div#top_nav a {
display: inline-block;
position: relative;
}
div#top_nav a:hover{
color: orange;
}
div#top_nav a:before{
content: "";
position: absolute;
width: 100%;
height: 2px;
bottom: -3px;
left: 0;
background-color: orange;
visibility: hidden;
-webkit-transform: scaleX(0);
transform: scaleX(0);
-webkit-transition: all 0.15s ease-in-out 0s;
transition: all 0.15s ease-in-out 0s;
}
div#top_nav a:hover:before {
visibility: visible;
-webkit-transform: scaleX(1);
transform: scaleX(1);
}
.active {
color: orange;
}
Hope this will help you. I have added this simple element.
div#top_nav a:hover:before , div#top_nav a.active:before
a {
text-decoration: none;
}
div#top_nav{
text-align: center;
}
div#top_nav li{
display: inline;
padding: 15px;
}
div#top_nav a {
display: inline-block;
position: relative;
}
div#top_nav a:hover{
color: orange;
}
div#top_nav a:before{
content: "";
position: absolute;
width: 100%;
height: 2px;
bottom: -3px;
left: 0;
background-color: orange;
visibility: hidden;
-webkit-transform: scaleX(0);
transform: scaleX(0);
-webkit-transition: all 0.15s ease-in-out 0s;
transition: all 0.15s ease-in-out 0s;
}
div#top_nav a:hover:before , div#top_nav a.active:before {
visibility: visible;
-webkit-transform: scaleX(1);
transform: scaleX(1);
}
.active {
color: orange;
}
<div id="top_nav">
<ul>
<li class="mainMenu-itemLevel1">
seite1</li>
<li class="mainMenu-itemLevel1">
seite2
</li><li class="mainMenu-itemLevel1">
seite3</li>
<li class="mainMenu-itemLevel1">
seite4</li>
<li class="mainMenu-itemLevel1">
Seite5 lang Hover</li>
</ul>
</div>
Hope this will help you.
You need to use javascript to do this.
Your javascript would add a class, like active to the relevant menu item, and you can then use your css to style it appropriately.
After adding the active class to the element, to apply your orange style use this:
div#top_nav.active a{
color: orange;
}
Note the addition of .active which selects only active items, and the omission of :hover on the link, since you no longer care about hover.
You may find the , css operator useful here, for applying the same styles to different selectors (active, and hover) as shown in my example below:
var items = document.getElementsByClassName('item');
var activeClassName = 'active';
function unselectItems() {
for (var i = 0; i < items.length; i++) {
items[i].classList.remove(activeClassName);
}
}
function selectItem(item) {
unselectItems();
item.classList.add(activeClassName);
}
function onItemClick(event) {
selectItem(event.target);
}
for (var i = 0; i < items.length; i++) {
items[i].addEventListener('click', onItemClick);
}
span {
border: 1px solid black;
padding: 5px;
}
span:hover, span.active {
color: white;
background-color: black;
}
<nav>
<span class="item">Home</span>
<span class="item">About</span>
<span class="item">Contact</span>
<nav>

Sizing sliding underline

I want to make the sliding underline to run from left to right when i hover, and also set up the width of the line from the 1st letter to the last, and not bigger. How can i do that?
.nav-bar a:hover {
color: #000;
}
.nav-bar a:before {
content: "";
position: absolute;
width: 100%;
height: 1px;
bottom: 0;
left: 0;
background-color: #000;
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;
}
.nav-bar a:hover:before {
visibility: visible;
-webkit-transform: scaleX(1);
transform: scaleX(1);
}
<div class="nav-bar">
<ul>
<li>RETROSPECTIVE SHOW /2006/</li>
<li>TEXTS</li>
<li>BIBLOGRAPHY</li>
</ul>
</div>
You can use display: inline-block; to keep the fixed width. And for underlining you can use pseudo-classes like :before and :after.
Have a look at the snippet below:
/* LEFT TO RIGHT */
.sliding-left-to-right {
display: inline-block;
margin: 0;
}
.sliding-left-to-right:after {
content: '';
display: block;
height: 3px;
width: 0;
background: transparent;
transition: width .5s ease, background-color .5s ease;
}
.sliding-left-to-right:hover:after {
width: 100%;
background: blue;
}
/* LAYOUT STYLING */
body {
margin: 20px;
}
a {
text-decoration: none;
font-size: 20px;
font-weight: bold;
color: blue;
}
a:hover {
color: blue;
text-decoration: none;
cursor: pointer;
}
<a class="sliding-left-to-right">Underline – Left to Right</a>
Hope this helps!

Pure css gradually change text on hover

I'm trying to gradually change an element's text while hovering, however it's not working for me.
I have this CSS:
.author-details > div a {
display: inline-block;
width: 30%;
float: none !important;
background-color: #1ABC9C;
color: #fff;
padding: 2% 3% 2% 3%;
border-radius: 7%;
font-weight: normal;
font-size: 16px;
-webkit-transition: background 0.35s linear;
-moz-transition: background 0.35s linear;
-ms-transition: background 0.35s linear;
-o-transition: background 0.35s linear;
transition: background 0.35s linear;
-webkit-box-shadow: 0px 5px 13px -8px rgba(0,0,0,0.45);
-moz-box-shadow: 0px 5px 13px -8px rgba(0,0,0,0.45);
box-shadow: 0px 5px 13px -8px rgba(0,0,0,0.45);
}
.author-details > div a:after {
content: 'Others';
}
.author-details > div a:hover {
background-color: #5DADE2;
}
.author-details > div a:hover:after {
-webkit-animation:fade-in 0.35s ease-in;
}
#-webkit-keyframes fade-in{
0%{
opacity:1;
top:0px;
}
50%{
opacity:0;
top:-5px;
content: 'Me';
}
100%{
opacity:1;
top:-5px;
}
}
And this HTML:
<div><label>View as: </label> </div>
However when I'm hovering on the element the text doesn't change. I want to make it change to "Me" when I'm hovering over it and return to "Others" when I'm not. How can I do that?
Here's a jsFiddle: http://jsfiddle.net/2fgy912p/
Code: http://codepen.io/anon/pen/Qbdvob
This effect works by using hover state to set opacity of absolutely positioned elements' opacity on and off. And they have transition applied so fade in and out effect is achieved.
Jade styled html:
.widget
span view as:
input(type='checkbox',id='toggle')
label.select(for='toggle')
.default others
.hovered you
Css:
* {
margin: 0;
padding: 0;
}
.widget {
font-family: Open Sans;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.widget span {
vertical-align: top;
line-height: 30px;
}
label.select {
user-select: none;
cursor: pointer;
background-color: #3ce;
color: #fff;
border-radius: 2px;
width: 60px;
vertical-align: top;
position: relative;
height: 30px;
display: inline-block;
}
label.select .default,
label.select .hovered {
transition: opacity 1s;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
opacity: 1;
}
label.select .hovered {
opacity: 0;
}
label.select:hover {
background-color: #36f;
}
label.select .default {
opacity: 1;
}
label.select .hovered {
opacity: 0;
}
label.select:hover .default {
opacity: 0;
}
label.select:hover .hovered {
opacity: 1;
}
You're not defining text to replace when hover the link. Should be:
.author-details > div a:after {
content: 'Others';
}
.author-details > div a:hover:after {
content: 'Me';
}
FIDDLE: https://jsfiddle.net/lmgonzalves/2fgy912p/3/
EDIT1:
I make a few changes to add transitions. See if this is want you want: https://jsfiddle.net/lmgonzalves/2fgy912p/7/
EDIT2:
I hardcoded the top property on each element, that should work, although I see working fine. Check: https://jsfiddle.net/lmgonzalves/2fgy912p/9/

Trying to get underline to start relative to the nav menu item in SCSS

I'm trying to implement a menu nav bar that on hover highlights the menu item with an underline animation from LEFT to RIGHT.
Currently I have the underline animating from the center of the menu item to the outside.
I have tried searchng for a solution to this but can't figure out what I'm doing wrong.
Here is a link to the project on codepen http://codepen.io/anon/pen/JowgqP
HTML
<menu>
<p><strong>Home</strong>
<strong>About</strong>
<strong>Portfolio</strong>
<strong>Contact</strong> <strong>
<p class="note">This is a recreation of the link hover effect from factmag.com</small>
</menu>
CSS (SCSS)
#import url(http://fonts.googleapis.com/css?family=Noto+Serif:400,700,400italic);
$link-color: #E71818;
$text-color: black;
$article-font: Noto serif, serif;
menu {
color: $text-color;
font-family: $article-font;
max-width: 30em;
}
p {
font-size: 18px;
line-height: 1.5;
}
menu a {
#extend %fancy-link;
}
.note {
display: inline-block;
border-top: 1px solid $link-color;
color: #777;
font-size: .8em;
font-style: italic;
margin-top: 2em;
padding-top: 1em;
}
%fancy-link {
color: $link-color;
position: relative;
text-decoration: none;
transition: all 0.15s ease-out;
&:before {
content: "";
position: absolute;
width: 100%;
height: 1px;
bottom: 0px;
left: 0;
background: #f00;
visibility: hidden;
transform: scaleX(0);
transition: all 0.3s ease-in-out 0s;
}
&:hover {
transition: all 0.15s ease-out;
&:before {
visibility: visible;
transform: scaleX(1);
}
}
}
The default transformation point is center center...or rather 50% 50% for ease of reference. (For 2 dimensions...we'll leave out z offsets for now.)
You would have to amend this so that the origin is now center left
&:before {
content: "";
position: absolute;
width: 100%;
height: 1px;
bottom: 0px;
left: 0;
background: #f00;
visibility: hidden;
transform: scaleX(0);
transform-origin: center left; /* here */
transition: all 0.3s ease-in-out 0s;
}
Codepen Demo
Transform-Origin # MDN