Pseudo Element ::before Hiding Sibling Element's Content - html

I want to create a transition effect when hovering over my list element (or alternatively my anchor tags within these list elements).
Unfortunately, when I use my created transition the ::before pseudo-element (or the ::after, I'm not sure) are hiding what is technically its sibling content, that being the text within the anchor tags.
I've tried manipulating the z-index on the ul, li and a tags to no avail. The problem likely lies within my use of position: absolute in my transitions but I can't tell what I'm doing wrong.
Here's the HTML and CSS and a JSFiddle link
html, body {
height: 100%;
margin: 0;
padding: 0;
font-family: 'Open Sans', sans-serif;
}
#headercontainer {
background-color: #4f2f65;
height: 125px;
position: relative;
}
#headercontainer ul {
height: 100%;
display: table;
text-align: center;
list-style: none;
margin: 0;
padding: 0;
}
#sitelogo {
padding-top: 0px;
}
#headercontainer ul li {
display: table-cell;
vertical-align: middle;
position: relative;
}
#headercontainer ul li a {
color: #fff;
font-size: 20px;
text-decoration: none;
}
a::before {
content: '';
display: block;
height: 0px;
background-color: #fff;
position: absolute;
bottom: 0;
width: 100%;
transition: all ease-in-out 200ms;
}
a:hover::before {
height: 125px;
}
header::after {
content: '';
display: table;
clear: both;
}
#headerlinkslist a:hover {
color: red;
}
.headerlinks {
padding-left: 80px;
padding-right: 80px;
}
<body>
<header>
<div id="headercontainer">
<ul id="headerlinkslist">
<li id="sitelogo"></li>
<li>RULES</li>
<li>NEWS</li>
<li>STATS</li>
<li>SUBMIT</li>
<li>LOGIN / REGISTER</li>
</div>
</header>
</body>

give the parent li a z-index, then use z-index: -1 on the pseudo element to push it behind the a but on top of the li.
You also need to close your ul
html,
body {
height: 100%;
margin: 0;
padding: 0;
font-family: 'Open Sans', sans-serif;
}
#headercontainer {
background-color: #4f2f65;
height: 125px;
position: relative;
}
#headercontainer ul {
height: 100%;
display: table;
text-align: center;
list-style: none;
margin: 0;
padding: 0;
}
#sitelogo {
padding-top: 0px;
}
#headercontainer ul li {
display: table-cell;
vertical-align: middle;
position: relative;
z-index: 1;
}
#headercontainer ul li a {
color: #fff;
font-size: 20px;
text-decoration: none;
transition: color .25s;
}
a::before {
content: '';
display: block;
height: 0px;
background-color: #fff;
position: absolute;
bottom: 0;
width: 100%;
transition: all ease-in-out 200ms;
z-index: -1;
}
a:hover::before {
height: 125px;
}
header::after {
content: '';
display: table;
clear: both;
}
#headerlinkslist a:hover {
color: red;
}
.headerlinks {
padding-left: 80px;
padding-right: 80px;
}
<body>
<header>
<div id="headercontainer">
<ul id="headerlinkslist">
<li id="sitelogo"></li>
<li>RULES</li>
<li>NEWS</li>
<li>STATS</li>
<li>SUBMIT</li>
<li>LOGIN / REGISTER</li>
</ul>
</div>
</header>
</body>

Related

Duration for Bottom border using CSS

I'm creating navbar with submenu. The elements of the navbar have a bottom border that becomes visible when hovered on. Further, a submenu is also visible. Currently, the bottom border goes invisible when the cursor is moved to submenu. I want it to be visible as long as the submenu is open.
nav {
display: inline-flex;
width: 100%;
}
.nav-list {
display: flex;
width: 100%;
margin-top: .7rem;
/*Use this to change the postition of dropdown*/
padding-left: 1.1rem;
/*Use this to move the dropdown left and right*/
}
.nav-list li {
position: relative;
}
.nav-list>li>a {
color: black;
display: block;
font-size: 1rem;
padding: 1.3rem 1rem;
text-transform: uppercase;
}
.nav-list>li>a::after {
content: "";
position: absolute;
background-color: #ff2a00;
height: 4px;
width: 0;
left: 0;
bottom: -0.5px;
}
.nav-list>li>a:hover:after {
width: 100%;
}
.sub-menu {
display: flex;
position: absolute;
box-sizing: border-box;
background-color: black;
visibility: hidden;
top: 3.89rem;
/*adjust postion */
left: -4rem;
width: 82.5rem;
height: 35rem;
z-index: 5000;
}
.sub-menu a {
position: relative;
top: 2rem;
color: white;
font-size: 1.1rem;
font-weight: 200;
padding: 3rem 40px 0 40px;
}
.sub-menu a:hover {
color: #7e7978;
}
<div class="main" id="navbar">
<nav>
<ul class="nav-list">
<li>
Men
<ul class="sub-menu">
<li>shirts </li>
</ul>
</li>
</ul>
</nav>
</div>
I have added the following code to the .nav-list li:hover .sub-menu block
.nav-list>li:hover .sub-menu {
visibility: visible;
}
This makes sure that the sub-menu is visible as long as the parent element is hovered.
And also added the following code to the .nav-list>li>a:hover:after
.nav-list>li:hover>a::after {
width: 100%;
}
This makes sure that the bottom border is visible as long as the parent element is hovered.
nav {
display: inline-flex;
width: 100%;
}
.nav-list {
display: flex;
width: 100%;
margin-top: .7rem;
/*Use this to change the postition of dropdown*/
padding-left: 1.1rem;
/*Use this to move the dropdown left and right*/
}
.nav-list li {
position: relative;
}
.nav-list>li>a {
color: black;
display: block;
font-size: 1rem;
padding: 1.3rem 1rem;
text-transform: uppercase;
}
.nav-list>li>a::after {
content: "";
position: absolute;
background-color: #ff2a00;
height: 4px;
width: 0;
left: 0;
bottom: -0.5px;
}
.nav-list>li:hover>a::after {
width: 100%;
}
.nav-list>li:hover .sub-menu {
visibility: visible;
}
.sub-menu {
display: flex;
position: absolute;
box-sizing: border-box;
background-color: black;
visibility: hidden;
top: 3.89rem;
/*adjust postion */
left: -4rem;
width: 82.5rem;
height: 35rem;
z-index: 5000;
}
.sub-menu a {
position: relative;
top: 2rem;
color: white;
font-size: 1.1rem;
font-weight: 200;
padding: 3rem 40px 0 40px;
}
.sub-menu a:hover {
color: #7e7978;
}
.nav-list>li:hover .sub-menu {
visibility: visible;
}
.nav-list>li:hover>a::after {
width: 100%;
}
<div class="main" id="navbar">
<nav>
<ul class="nav-list">
<li>
Men
<ul class="sub-menu">
<li>shirts </li>
</ul>
</li>
</ul>
</nav>
</div>

How do I animate a link underline to the width of the link, not the ul?

I have the following link hover animation:
*,
*::before,
*::after {
box-sizing: border-box;
}
html,
body {
margin: 0;
padding: 0;
width: 100vw;
height: 100vh;
}
body {
font-family: Arial;
background-color: red;
}
ul {
list-style-type: none;
width: 33vw;
margin: 0;
padding: 0;
}
li {
margin: 0 10px;
padding: 2px;
}
a {
text-decoration: none;
color: white;
font-size: 25px;
}
a::after {
content: "";
width: 0;
height: 2px;
background-color: white;
display: block;
transition: width 0.5s;
}
a:hover::after {
width: 100%;
}
<!DOCTYPE html>
<html>
<body>
<ul>
<li>Home</li>
<li>About Us</li>
<li>Events</li>
<li>Contact</li>
</ul>
</body>
</html>
In the above snippet, when I hover over each of the links, the underline properly animates. However, the underline ends at the width of the ul, not at the width of each link itself (e.g if I hover on the "Home" link, the animated underline goes way past the word "Home" itself, all the way to the end of the ul). How should I change my CSS for the a::after or a:hover::after pseudo-elements so that I get the behavior I'm looking for?
Make the link inline-block
*,
*::before,
*::after {
box-sizing: border-box;
}
html,
body {
margin: 0;
padding: 0;
width: 100vw;
height: 100vh;
}
body {
font-family: Arial;
background-color: red;
}
ul {
list-style-type: none;
width: 33vw;
margin: 0;
padding: 0;
}
li {
margin: 0 10px;
padding: 2px;
}
a {
text-decoration: none;
color: white;
font-size: 25px;
display: inline-block;
}
a::after {
content: "";
width: 0;
height: 2px;
background-color: white;
display: block;
transition: width 0.5s;
}
a:hover::after {
width: 100%;
}
<ul>
<li>Home</li>
<li>About Us</li>
<li>Events</li>
<li>Contact</li>
</ul>
just use inline block to your style
a {
display: inline-block;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
html,
body {
margin: 0;
padding: 0;
width: 100vw;
height: 100vh;
}
body {
font-family: Arial;
background-color: red;
}
ul {
list-style-type: none;
width: 33vw;
margin: 0;
padding: 0;
}
li {
margin: 0 10px;
padding: 2px;
}
a {
text-decoration: none;
color: white;
font-size: 25px;
display: inline-block;
}
a::after {
content: "";
width: 0;
height: 2px;
background-color: white;
display: block;
transition: width 0.5s;
}
a:hover::after {
width: 100%;
}
<!DOCTYPE html>
<html>
<body>
<ul>
<li>Home</li>
<li>About Us</li>
<li>Events</li>
<li>Contact</li>
</ul>
</body>
</html>
I just actually finished setting this up, but did not even want to have any extra underline for any of my links. So I fixed it with pure css (scss actually) as well, but got specific. This is the css (scss) I used to make the underline only span the width of the text:
.main-nav {
background: rgba(103, 128, 159, 1);
display: block;
height: 100vh;
left: 0;
right: 0;
margin-top: 0;
margin-left: 0;
margin-right: 0;
padding-top: 5rem;
overflow-y: hidden;
position: fixed;
top: 0;
/* hide the menu above the screen by default */
transform: translateX(-100%);
/* transition adds a little animation when sliding in and out the menu */
transition: transform 0.2s ease;
width: 100vw;
/* needed for me because of my intro box in index.html.
Otherwise navigation backgrop would be behind the intro box when opened */
z-index: 10;
/* so that the nav link underlining from framer motion does not span across the width of the main-nav backdrop */
& li > a {
display: block;
width: 6rem;
}
& li:nth-of-type(1) > a {
width: 3.5rem;
}
& li:nth-of-type(2) > a {
width: 3.5rem;
}
& li:nth-of-type(3) > a {
width: 2.75rem;
}
& li:nth-of-type(4) > a {
width: 4.75rem;
}
& li:nth-of-type(5) > a {
width: 6.5rem;
}
& li:nth-of-type(6) > a {
width: 2.75rem;
}
}
.main-nav is the class for the ul. I just set an arbitrary initial width, and then the specific ones for the specific anchor elements.

Getting strange flickering effect

just doing a simple header with a nav element, and I am getting a strange flickering effect on the font when I mouse over the header. Here is the code and and a gif. The links have a :hover rule that changes the color when you mouse over them but that is not the issue as I have tried removing that rule and the flickering still happens. Any help much appreciated. Thank you for your time
.cf:before,
.cf:after {
content: "";
display: table;
}
.cf:after {
clear: both;
}
html,
body {
margin: 0px;
padding: 0px;
height: 100vh;
}
#header {
position: absolute;
width: 100vw;
height: 10vh;
background-color: #666;
opacity: 1;
z-index: 6;
}
#menu {
line-height: 10vh;
float: right;
margin-right: 5vw;
}
#title {
margin-left: 10vw;
line-height: 10vh;
float: left;
}
li,
ul {
padding: 0;
margin: 0;
list-style: none;
float: right;
}
li a {
display: block;
line-height: 10vh;
padding: 0 1em;
font-size: 1.3em;
color: rgb(255, 255, 255);
text-decoration: none;
}
ul {
margin-right: 2em;
}
nav {}
a:visited {
text-decoration: none;
}
a:hover {
text-decoration: none;
color: #FFBB3F
}
<div id="header">
<div id="title">
<h1>Title <span id="subtitle">subtitle</span></h1>
</div>
<nav class="cf" id="menu">
<ul>
<li>about</li>
<li>gallery</li>
<li>contact</li>
<li>shop</li>
</ul>
</nav>
</div>

Height 100% on a absolute positioned element

I was trying to make navigation bar of a demo present here http://www.templatemonster.com/demo/51129.html
HTML :
<div class="main-container">
<div class="top-nav-wrap">
<div class="top-nav">
<ul>
<li class="border"><a href="#" >HOME</a></li>
<li class="border submenu"><a href="#" >BLOG</a>
<div class="submenu-wrap">
<ul class="submenu-1">
<li>TESTIMONIALS</li>
<li>ARCHIVES</li>
<li>FAQS</li>
</ul>
</div>
</li>
<li class="border"><a href="#" >SERVICES</a></li>
<li class="border"><a href="#" >OUR GALLERY</a></li>
<li class="border"><a href="#" >CONTACTS</a></li>
</ul>
</div>
</div>
<div class="top-container">
</div>
</div>
CSS:
* {
margin: 0;
padding: 0;
}
body {
background-image: url(../images/header-img.jpg);
font-family: 'Roboto Condensed', sans-serif;
height: 1900px;
}
.top-container {
overflow: hidden;
}
.top-nav-wrap {
width: 100%;
}
div.top-nav-scrolled.top-nav-wrap {
position: fixed;
top: 0;
left: 0;
background: white;
}
.top-nav {
width: 1200px;
margin: auto;
/*overflow: hidden;*/
}
.top-nav ul {
/*overflow: hidden;*/
list-style: none;
}
.top-nav ul li {
position: relative;
float: left;
padding-top: 30px;
margin-left: 50px;
padding-bottom: 10px;
}
.top-nav ul li:first-child {
margin-left: 0;
}
.top-nav li a {
text-decoration: none;
font-weight: 600;
font-size: 20px;
letter-spacing: 1px;
color: #ba4b07;
}
.top-nav li.border::before {
position: absolute;
left: -25px;
content: '\\';
font-size: 20px;
color: #ba4b07;
}
.top-nav li.border:first-child::before {
content: '';
}
.top-nav li.border> a::after {
position: absolute;
top: -30px;
left: 0;
content: '';
display: block;
width: 100%;
height: 20px;
background: #ba4b07;
transition: all 0.3s ease;
}
.top-nav li.border a.hoverNav::after {
top:0px;
}
.submenu-wrap {
height: 0px;
position: absolute;
top: 100%;
overflow: hidden;
transition: all 0.3s ease;
}
.submenu:hover > div {
height: 100%;
}
ul.submenu-1 {
width: 300px;
padding-top: 15px;
padding-bottom: 30px;
background:#ba4b07;
}
ul.submenu-1 li{
padding: 0px;
float: none;
margin: 0;
}
ul.submenu-1 li a {
display: block;
padding: 20px;
color: white;
font-size: 1em;
}
ul.submenu-1 li:hover {
background: white;
}
ul.submenu-1 li:hover a {
color: #ba4b07;
}
Js:
$(function(){
$('.top-nav ul li a').on('mouseover',function(){
$(this).addClass('hoverNav');
}).on('mouseout',function(){
$(this).removeClass('hoverNav');
});
$(window).on('scroll',function(){
$('.top-nav-wrap').addClass('top-nav-scrolled');
if($(window).scrollTop()==0){
$('.top-nav-wrap').removeClass('top-nav-scrolled');
}
});
});
The problem over here is .submenu:hover > div having height:100%;.
I saw many answers over here regarding height 100% but was not able to understand.
height:100% over here is taking only some part of the whole div and not the full.
I could have used hardcoded pixels but all my submenus are of different size and using the same class.
EDIT : Moreover using height:auto wont let my css transition to work. and same with using max-height.
I want my css transition to stay.
Change your sub-menu to height:auto, thus it calculates height according to the child elements present inside, as below.
Update to achieve height transition, you could try something as below, still height will be auto, but could transit using inner elements.
.submenu:hover >.submenu-wrap {
height:auto;
}
.submenu:hover >.submenu-wrap> ul.submenu-1 {
padding-top: 15px;
padding-bottom: 30px;
}
.submenu:hover >.submenu-wrap> ul.submenu-1 li a {
padding-top: 20px;
padding-bottom: 20px;
}
Check updated jsFiddle
You can use this code it may help you.
CSS
* {
margin: 0;
padding: 0;
}
body {
background-image: url(../images/header-img.jpg);
font-family: 'Roboto Condensed', sans-serif;
height: 1900px;
}
.top-container {
overflow: hidden;
}
.top-nav-wrap {
width: 100%;
}
div.top-nav-scrolled.top-nav-wrap {
position: fixed;
top: 0;
left: 0;
background: white;
}
.top-nav {
width: 1200px;
margin: auto;
/*overflow: hidden;*/
}
.top-nav ul {
/*overflow: hidden;*/
list-style: none;
}
.top-nav ul li {
position: relative;
float: left;
padding-top: 30px;
margin-left: 50px;
padding-bottom: 10px;
}
.top-nav ul li:first-child {
margin-left: 0;
}
.top-nav li a {
text-decoration: none;
font-weight: 600;
font-size: 20px;
letter-spacing: 1px;
color: #ba4b07;
}
.top-nav li.border::before {
position: absolute;
left: -25px;
content: '\\';
font-size: 20px;
color: #ba4b07;
}
.top-nav li.border:first-child::before {
content: '';
}
.top-nav li.border> a::after {
position: absolute;
top: -30px;
left: 0;
content: '';
display: block;
width: 100%;
height: 20px;
background: #ba4b07;
transition: all 0.3s ease;
}
.top-nav li.border a.hoverNav::after {
top:0px;
}
.submenu-wrap {
/*height: 0px;*/
position: absolute;
top: 100%;
overflow: hidden;
/*transition: all 0.3s ease;*/
display: none;
}
.submenu:hover > div {
/* height: 100%;*/
}
ul.submenu-1 {
width: 300px;
padding-top: 15px;
padding-bottom: 30px;
background:#ba4b07;
}
ul.submenu-1 li{
padding: 0px;
float: none;
margin: 0;
}
ul.submenu-1 li a {
display: block;
padding: 20px;
color: white;
font-size: 1em;
}
ul.submenu-1 li:hover {
background: white;
}
ul.submenu-1 li:hover a {
color: #ba4b07;
}
JS
$(function(){
$(".top-nav ul li").hover(function(){
$(this).find(".submenu-wrap").slideToggle();
});
$('.top-nav ul li').on('mouseover',function(){
$(this).children().addClass('hoverNav');
}).on('mouseout',function(){
$(this).children().removeClass('hoverNav');
});
$(window).on('scroll',function(){
$('.top-nav-wrap').addClass('top-nav-scrolled');
if($(window).scrollTop()==0){
$('.top-nav-wrap').removeClass('top-nav-scrolled');
}
});
});

In a nested menu, how to make sub menus 100% and aligned to left?

Here is a basical menu:
http://jsbin.com/aTupIZIp/3/edit
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>
<ul class="nav">
<li><a>Home</a></li>
<li>
<a>Our Staff</a>
<div class="pos-fix">
<ul class="vert">
<li><a>Jon Skeet</a></li>
<li><a>Spiderman</a></li>
</ul>
</div>
</li>
<li><a>Contact Us</a></li>
</ul>
</body>
</html>
body, ul, li, a {
margin: 0;
padding: 0;
}
a {
cursor: pointer;
}
.nav {
list-style: none;
width: 100%;
display: table;
}
.nav li {
display: table-cell;
background: red;
}
.nav a {
display: block;
text-align: center;
padding: 10px;
}
.pos-fix {
position: relative;
}
.nav a:before {
content: '';
display: inline-block;
height: 30px;
width: 30px;
background: url(http://placehold.it/30x30);
float: left;
margin: -5px 0 0 0;
}
.nav a:hover {
background: black;
color: yellow;
}
.nav li:hover .vert {
display: block;
}
.vert {
display: none;
width: 100%;
position: absolute;
}
.vert li {
width: 100%;
display: block;
}
lets look at the submenu (our staff / John Skeet . Spiderman). How to set them to be 100% width and aligned to left?
So far I tried to make it width: 10000px; overflow: hidden; but horizontal scrollbars still appears. And even position: absolute; left: 0; screws all up
Your pos-fix div was causing the problem. Remove it.
FIDDLE
(Relevant) CSS
.vert {
display: none;
width: 100%;
position: absolute;
top: 40px;
left:0;
}
.vert li {
width: 100%;
display: block;
text-align: left;
}
.vert a {
text-align: left;
}
.vert a:before {
margin-right: 10px;
}
Do this:
ul.nav .pos-fix {
left: 0;
margin: 0;
position: absolute;
right: 0;
}