Max height of ul is limited to a single nested li item - html

Making a slide down drop menu animation, if I set max height to 100% the <ul> will only extend its height to the first nested <li>. I can set the max-height in the Keyframe to 400%, but this causes to animation to go twice as fast in other drop downs with less submenus. The height of the <ul> before I hover over seems to be the full size when debugging, not sure why it gets limited in the animation.
And as a secondary question, will I run into browser support issues using animations like this?
JSFiddle
#keyframes slideDown {
0% {
max-height: 0%;
opacity: .2;
}
100% {
max-height: 400%;
opacity: 1;
}
}
#menuTabs {
float: left;
position: absolute;
margin-left: 0px;
background: #256AAA none repeat scroll 0% 0%;
width: 100%;
overflow: visible;
}
#menuTabs ul {
left: 50%;
margin: 0px;
clear: left;
float: left;
padding: 0px;
font-size: 15px;
position: relative;
text-align: center;
font-family: helvetica;
list-style: outside none none;
}
#menuTabs ul li {
margin:0;
padding:0;
right:50%;
float:left;
display:block;
list-style:none;
min-width: 170px;
max-width: 170px;
position:relative;
}
#menuTabs ul li a {
color:#000;
display:block;
background:#ddd;
padding:0px 50px;
line-height:1.3em;
text-decoration:none;
font-family:'Oxygen', sans-serif;
color: #FFF;
margin-top: 0px;
font-weight: bold;
padding: 15px 50px;
text-decoration: none;
background: #Blue;
}
#menuTabs ul li:hover > a {
visibility: visible;
text-decoration: none;
background: #CCC;
}
ul#menu li.selected a {
color: #000;
background-color: #fff;
}
#menuTabs ul li ul {
margin: 0;
padding: 0;
width: 100%;
visibility: hidden;
overflow: hidden;
position: absolute;
left: 0%;
max-height: 0%;
}
#menuTabs ul li ul a {
z-index: 1;
display: block;
font-size: 12px;
max-width: 70px;
min-width: 120px;
min-height: 22px;
overflow: visible;
position: relative;
padding: 14px 25px;
background: #256AAA none repeat scroll 0% 0%;
}
#menuTabs ul li ul a:hover {
background: #CCC;
}
#menuTabs ul li:hover ul {
visibility: visible;
position: absolute;
background: #CCC;
}
#menuTabs ul li:hover ul {
max-height: 0%;
animation-name: slideDown;
animation-duration: 2s;
animation-fill-mode: forwards;
}
#menuTabs ul li ul li {
left: 0%;
display: block;
}
<div id="menuTabs">
<ul id="menu">
<li> Services
<ul id="class">
<li id="srv1"> SubMenu
</li>
<li id="srv2"> SubMenu2
</li>
</ul>
<li>Resources
<ul>
<li> SubMenu2</li>
<li> SubMenu3</li>
<li> SubMenu4</li>
<li> SubMenu5</li>
</ul>
</li>
</li>
</ul>
</div>

I would do it by just using transition instead of keyframes for that, it runs smoother, and much easier. I haven't found a way to do the dynamic height thing, so I think you'll have to pick a height with the max number of items you're possibility going to have.
jsfiddle
#menuTabs ul li ul {
...
max-height: 0;
transition: all .1s ease-out;
opacity: .5;
}
#menuTabs ul li:hover ul {
...
max-height: 400%;
transition: all .25s ease-in;
opacity: 1;
}

Related

Borders transfer animation with being visible all the time

I've been wondering how could it be possible to implement transfer animation of borders (or box-shadow) from one element to another.
Here's raw example,
.item {
float: left;
width: 33.33%;
padding: 0;
text-align: center;
}
.item:hover {
box-shadow: 0 0 0 3px black;
/* border: 3px solid black; */
}
.sections {
width: 100%;
height: 100%;
margin: 0 auto;
}
ul {
list-style-type: none;
}
a:hover {
text-decoration: none;
}
a {
text-decoration: none;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div class="sections">
<ul>
<li class="item">Element 1
</li>
<li class="item">Element 2
</li>
<li class="item">Element 3
</li>
</ul>
</div>
</body>
</html>
In this case "borders" is box-shadow or border in .item:hover class. As you can see, borders appears and destroys on hover event, but I need borders flowing from one li element to another li element without destroying, keeping being visible all the time.
I swear I've seen such thing on several web sites, could you suggest something with this one maybe with help of javascript?
Maybe this can help you
I got this from Codepen this is not my code
* {
box-sizing: border-box;
}
body {
font: 300 100% 'Helvetica Neue', Helvetica, Arial;
}
.container {
width: 50%;
margin: 0 auto;
}
ul li {
display: inline;
text-align: center;
}
a {
display: inline-block;
width: 25%;
padding: .75rem 0;
margin: 0;
text-decoration: none;
color: #333;
}
.two:hover ~ hr {
margin-left: 25%;
}
.three:hover ~ hr {
margin-left: 50%;
}
.four:hover ~ hr {
margin-left: 75%;
}
hr {
height: .25rem;
width: 25%;
margin: 0;
background: tomato;
border: none;
transition: .3s ease-in-out;
}
<div class="container">
<ul>
<li class="one">Uno</li><!--
--><li class="two">Dos</li><!--
--><li class="three">Tres</li><!--
--><li class="four">Quatro</li>
<hr />
</ul>
</div>
Source: https://codepen.io/rm/pen/ldhon
Hope it works for you
html {
font-family: 'Josefin Slab', 'Comfortaa', sans-serif;
font-size: 1.2em;
background: #eee;
}
ul {
position: relative;
width: 27em;
height: 2em;
margin: 100px auto;
padding: 0;
white-space: nowrap;
}
ul li {
display: inline;
text-align: center;
}
ul li a {
position: relative;
top: 0;
left: 0;
right: 25em;
bottom: 0;
display: inline-block;
-moz-box-sizing: border-box;
box-sizing: border-box;
padding: .4em .2em;
color: #222;
text-decoration: none;
text-shadow: 0 1px 0 white;
/*transition*/
-webkit-transition: width .3s,right .3s;
-moz-transition: width .3s,right .3s;
-o-transition: width .3s,right .3s;
transition: width .3s,right .3s;
}
ul li:nth-child(1) a { width: 4em; }
ul li:nth-child(2) a { width: 4em; }
ul li:nth-child(3) a { width: 4em; }
ul li:nth-child(4) a { width: 12em; }
ul li:nth-child(5) a { width: 5em; }
ul li:last-child a::after {
content: "";
position: absolute;
right: inherit;
bottom: -3px;
width: inherit;
height: 38px;
background: #ccc;
pointer-events: none;
-webkit-transition: all .5s ease;
-moz-transition: all .5s ease;
-o-transition: all .5s ease;
transition: all .5s ease;
border: 1px solid transparent;
background: transparent;
}
ul li:nth-child(1) ~ li:last-child a {
right: 25em;
width: 4em;
}
ul li:nth-child(2):hover ~ li:last-child a {
right: 21em;
width: 4em;
}
ul li:nth-child(3):hover ~ li:last-child a {
right: 17em;
width: 4em;
}
ul li:nth-child(4):hover ~ li:last-child a {
right: 5em;
width: 12em;
}
ul li:nth-child(5):last-child:hover a {
right: 0;
width: 5em;
}
ul li:hover ~ li:last-child a::after,
ul li:last-child:hover a::after { border-color: red; }
ul li:last-child a {
min-width: 5em;
max-width: 5em;
}
ul li a:hover,
ul li a:focus {
color: red;
/*transition*/
-webkit-transition: width .3s,right .3s,background-color .3s;
-moz-transition: width .3s,right .3s,background-color .3s;
-o-transition: width .3s,right .3s,background-color .3s;
transition: width .3s,right .3s,background-color .3s;
}
ul li a:focus { border-bottom: 3px solid #c351fa; }
<ul>
<li>Home </li><!--
--><li> Lorem </li><!--
--><li> Ipsum </li><!--
--><li> Lorem dummy text</li><!--
--><li> Sit amet </li>
</ul>
We can use a pseudo element on the last li a element to show a border as CSS lets us select the last sibling element when any element in the list is hovered.
We can then set the border color and set the right position of this pseudo element and have it transition to the hovered li a element position.
It is possible to have a fairly general solution - setting a CSS variable to the number of elements in the list (and the transition time too if wanted) and (almost) everything else falls into place using CSS calc.
However, unfortunately, although CSS has the ability in theory to let you use the n value (in nth-child(n)) this only seems to work for pseudo element content at the moment so we can't use it to do calculations.
I have therefore put in a set of nth child settings in the CSS - currently there are 6 so you can have a list of up to 6 without changing anything except for --n. If you want more then add more.
Here's the snippet.
.sections ul {
--n: 3; /* the number of items in the list */
--t: 1s; /* the time taken to move to the new hover position */
--w: calc(100% / var(--n));
box-sizing: border-box;
padding: 20px 0;
margin: 0;
}
/* below is the original CSS */
.item {
float: left;
width: var(--w);
padding: 0;
text-align: center;
}
.item a {
text-align: center;
}
.sections {
width: 100%;
height: 100%;
margin: 0 auto;
}
ul {
list-style-type: none;
}
a:hover {
text-decoration: none;
}
a {
text-decoration: none;
}
/* end of the original CSS */
ul li:last-child a::after {
position: absolute;
content: '';
right: inherit;
width: var(--w);
height:1.5em;
transform: translateY(-0.3em);
pointer-events: none;
transition: right var(--t) ease;
}
ul li:nth-child(1):hover ~ li:last-child a {
right: calc(var(--w) * calc(var(--n) - 1));
}
ul li:nth-child(2):hover ~ li:last-child a { /*when you hover on the second element it changes the last element's a width and its position */
right: calc(var(--w) * calc(var(--n) - 2));
}
ul li:nth-child(3):hover a {
right: calc(var(--w) * calc(var(--n) - 3));
}
ul li:nth-child(4):hover a {
right: calc(var(--w) * calc(var(--n) - 4));
}
ul li:nth-child(5):hover a {
right: calc(var(--w) * calc(var(--n) - 5));
}
ul li:nth-child(6):hover a {
right: calc(var(--w) * calc(var(--n) - 6));
}
ul li:hover ~ li:last-child a::after,
ul li:last-child:hover a::after {
border: 2px solid black;
}
ul li a {
width: 100%;
}
<div class="sections">
<ul>
<li class="item">Element 1
</li>
<li class="item">Element 2
</li>
<li class="item">Element 3
</li>
</ul>
</div>

Why aren't nav bar buttons centered?

I have the code there
My question is, why aren't the buttons for different pages centered? This is more obvious when the site is minimized.
nav.stroke ul li a,
nav.fill ul li a {
position: relative;
}
nav.stroke ul li a:after,
nav.fill ul li a:after {
position: absolute;
bottom: 0;
left: 0;
right: 0;
margin: auto;
width: 0%;
content: '.';
color: transparent;
background: #aaa;
height: 1px;
}
nav.stroke ul li a:hover:after {
width: 100%;
}
nav.fill ul li a {
transition: all 2s;
}
nav.fill ul li a:after {
text-align: left;
content: '.';
margin: 0;
opacity: 0;
}
nav.fill ul li a:hover {
color: #fff;
z-index: 1;
}
nav.fill ul li a:hover:after {
z-index: -10;
animation: fill 1s forwards;
-webkit-animation: fill 1s forwards;
-moz-animation: fill 1s forwards;
opacity: 1;
}
h1,h3 {
text-align: center;
color: white;
}
li{
list-style-position: inside;
display: inline;
padding-left: 12px;
}
a{
padding: .2em .1em;
color:grey;
background-color: ;
}
}
.xy{
margin-top: 75px;
}
h1{
font-size: 45px;
}
h3{
font-size: 23px;
}
body{
background-color: #451255;
}
nav {
width: 70%;
margin: 0 auto;
background: #fff;
padding: 15px;
box-shadow: 0px 5px 0px #dedede;
position: center;
}
nav ul {
list-style: none;
text-align: center;
}
nav ul li {
display: inline-block;
}
nav ul li a {
display: block;
padding: 15px;
text-decoration: none;
color: #aaa;
font-weight: 800;
text-transform: uppercase;
margin: 0 10px;
}
nav ul li a,
nav ul li a:after,
nav ul li a:before {
transition: all .5s;
}
nav ul li a:hover {
color: #555;
}
#-webkit-keyframes fill {
0% {
width: 0%;
height: 1px;
}
50% {
width: 100%;
height: 1px;
}
100% {
width: 100%;
height: 100%;
background: #451255;
}
}
.btns,
.fill{
margin: auto;
position: center;
display: block;
}
So, I have that code, you can see on the link what it looks like. My problem is that it's not centered. And when I minimize it, the fact that it's not centered is more obvious. How could I fix that?
like #junkfoodjunkie already said, it's about basic CSS reset.
why? elements got initial CSS set, this is what's going on:
like you can see, your menu's items (blue part) are already centered but you've got initial -webkit-padding-start: 40px; (green part) and it's do the same as padding-left: 40px;, it takes not less than 40px from your menu so that's why it looks like the menu's items are not centered/stick to the right, so in order to fix it you need to overwrite the value of the <ul> element.
you're also set the <li> elements to padding-left: 12px; so the menu's items will not be centered perfectly. if you're not going to use some CSS reset then add .fill > ul {padding-left: 0;} to your CSS.
You're not resetting or eliminating default behavior. You have no margin or padding defined on the <ul>, and you have not reset the CSS to begin with, so there is a default padding and margin messing with you. Put margin: 0; padding: 0; on your <ul> and it should work.
Or, just do a full brutal reset: https://jsfiddle.net/efv8x1x2/1/
Added
* {
margin: 0;
padding: 0;
}
to the beginning of the stylesheet, and voila, centered.

Making navbar link filled while on current page

I am currently trying to create a navbar that fills when hovered over a link. However, I would also like to have the link filled (or highlighted) while on the relative page. Any help would be much appreciated!
Note: This code has been retrieved from an open source.I am new learner of web technologies and working for a web project.
/*NAVIGATION */
body {
font-family: 'Roboto', sans-serif;
padding: 0;
margin: 0;
}
small {
font-size: 12px;
color: rgba(0, 0, 0, 0.4);
}
h1 {
text-align: center;
padding: 50px 0;
font-weight: 800;
margin: 0;
letter-spacing: -1px;
color: inherit;
font-size: 40px;
}
h2 {
text-align: center;
font-size: 30px;
margin: 0;
font-weight: 300;
color: inherit;
padding: 50px;
}
.center {
text-align: center;
}
section {
height: 100vh;
}
nav {
width: 60%;
margin: 0 auto;
background: #fff;
padding: 10px 0;
box-shadow: 0px 5px 0px #dedede;
}
nav ul {
list-style: none;
text-align: center;
}
nav ul li {
display: inline-block;
}
nav ul li a {
display: block;
padding: 15px;
text-decoration: none;
color: #aaa;
font-weight: 800;
text-transform: uppercase;
margin: 0 10px;
}
nav ul li a,
nav ul li a:after,
nav ul li a:before {
transition: all .5s;
}
nav ul li a:hover {
color: #555;
}
/* stroke */
nav.stroke ul li a,
nav.fill ul li a {
position: relative;
}
nav.stroke ul li a:after,
nav.fill ul li a:after {
position: absolute;
bottom: 0;
left: 0;
right: 0;
margin: auto;
width: 0%;
content: '.';
color: transparent;
background: #aaa;
height: 1px;
}
nav.stroke ul li a:hover:after {
width: 100%;
}
nav.fill ul li a {
transition: all 2s;
}
nav.fill ul li a:after {
text-align: left;
content: '.';
margin: 0;
opacity: 0;
}
nav.fill ul li a:hover {
color: #fff;
z-index: 1;
}
nav.fill ul li a:hover:after {
z-index: -10;
animation: fill 1s forwards;
-webkit-animation: fill 1s forwards;
-moz-animation: fill 1s forwards;
opacity: 1;
}
/* Keyframes */
#-webkit-keyframes fill {
0% {
width: 0%;
height: 1px;
}
50% {
width: 100%;
height: 1px;
}
100% {
width: 100%;
height: 100%;
background: #333;
}
}
<section style="background: #2ecc71; color: rgba(0, 0, 0, 0.5);">
<h2>Nav bar test</h2>
<nav class="fill">
<ul>
<li>Home
</li>
<li>About
</li>
<li>Downloads
</li>
<li>More
</li>
<li>Contact
</li>
</ul>
</nav>
</section>
The best practice is just to add an "active" class to the current page button.
<li>Home</li>
And add "a.active" to every "a:hover" that you already have so it has the same css.
nav.fill ul li a:hover,
nav.fill ul li a.active { /* Here */
color: #fff;
z-index: 1;
}
nav.fill ul li a:hover:after,
nav.fill ul li a.active:after { /* Here */
z-index: -10;
animation: fill 1s forwards;
-webkit-animation: fill 1s forwards;
-moz-animation: fill 1s forwards;
opacity: 1;
}
nav.stroke ul li a:hover:after,
nav.stroke ul li a.active:after { /* Here */
width: 100%;
}
Here is an jsfiddle live example: https://jsfiddle.net/884o5sjs/
(To get help faster, remember to create your own jsfiddle next time)
You could add the class="active" to the current page dynamically with php (suggested) or even with jQuery (not suggested), but since it looks like you are using ".html" you will have to add it manually on each page.
Hope this helps.
Looks like you've already achieved your first task of having it highlight when hovered. I would do this in php because that's the language I'm most comfortable, but then you'd also have to run a web server on your computer so hopefully you get some more helpful tips from some of the Jscript pros on here. If you do have to resort to php, one way I commonly do this is by having a variable on the page that lets the header know what page you're on, and then a few if statements that coorespond and apply a .current-page style.
I'm probably doing it the long way, but I just haven't learned Javascript yet.
the if statement would look like this within the li of the ul of the nav... <li <?php if ($title == "Home) { echo "class='current-page'"; } ?>>Home and so on for each element in the ul with the corresponding title, and title declarations in the body of the page.

CSS Drop-Down Navigation Links Cramped

I'm trying to create a responsive, drop-down CSS menu, and I have a media query that targets mobile devices (760 pixels). I'm trying to make all the links occupy the entire width, and that goes well, but the problem is when I display the drop down menu when the width is less than 760 pixels, all of the links of the drop down menu are cramped into the navigation links. I would like to know how to solve this problem, because I have been thinking for a long time and haven't figured out a solution. I want the drop-down menu for services to be directly below services, and the final contact link to go below the drop-down menu. This is the problem:
Below is the HTML and the CSS, as well as a link to the JSFiddle.
HTML:
<div class="wrapper">
<ul class="links">
<li id="active">home
</li><li>about
</li><li>services
<ul class="links">
<li>web development
</li><li>design templates
</li><li>networking
</li><li>custom builds
</li>
</ul>
</li><li>contact</li>
</ul>
</div>
CSS:
html,
body {
margin: 0;
padding: 0;
font-family: Source Sans Pro, Helvetica, sans-serif;
}
.wrapper {
width: 100%;
height: auto;
}
ul.links {
margin: 0px;
padding: 0px;
list-style: none;
background-color: #EBEBEB;
}
ul.links a {
color: #737373;
text-decoration: none;
}
ul.links ul {
display: none;
position: absolute;
top: 100%;
left: 0;
background: #fff;
}
ul.links li {
background: none;
color: #737373;
display: inline-block;
position: relative;
font-size: 19px;
padding-top: 22px;
padding-bottom: 22px;
padding-left: 35px;
padding-right: 35px;
transition: background 0.2s linear 0s, color 0.2s linear 0s;
-webkit-transition: background 0.2s linear 0s, color 0.2s linear 0s;
}
ul.links ul li {
position: relative;
font-size: 18px;
display: block;
float: left;
width: 100%;
}
ul.links li:hover {
background-color: #6ECFFF;
}
ul.links li:hover ul {
display: block;
}
ul.links li:hover .link {
color: #F0F0F0;
}
ul.links ul li:hover .link2 {
color: #F0F0F0;
}
#active {
background-color: #6ECFFF;
}
#active a {
color: #F0F0F0;
}
#media screen and (max-width: 760px) {
ul.links li
{
width: 100%;
}
ul.links ul {
position: absolute;
left: 0;
}
ul.links ul li {
background: #EBEBEB;
}
}
JSFiddle: https://jsfiddle.net/7tkn7zzs/
You should make ul.links ul { to position: relative; in media query to display it proper.
ul.links ul {
position: relative;
left: 0;
}
Working Fiddle
ul.links ul {
position: relative;
left: -35px; /* equal to padding left */
}

CSS rotate making links unclickable unless double clicking

I can't seem to find the issue that is causing my links to only be clicked on the white portion. It's a "3D" button by that, I mean it is a link with CSS rotate transitions. I'm not able to find any solutions so I'm looking for some help!
Here's the codepen link.
HTML:
<nav>
<ul>
<li>Home
</li>
<li>Plans
</li>
<li>Forums
</li>
<li>Team
</li>
</ul>
</nav>
CSS
* {
box-sizing: border-box;
}
nav {
background: #e9e9e9;
margin: -1rem 0rem;
z-index: 0;
}
nav ul {
list-style: none;
}
nav ul li {
display: inline-block;
text-transform: uppercase;
font-size: 1.5rem;
letter-spacing: 0.05rem;
}
nav ul li a {
display: inline-block;
padding: 1rem;
color: #000;
text-decoration: none;
transition: transform 0.3s ease 0s;
transform-origin: 50% 0px 0px;
transform-style: preserve-3d;
}
nav ul li a.current {
color: #ffc400;
}
nav ul li a: hover {
background: #e9e9e9;
color: #000;
transform: rotateX(90deg) translateY(-22px);
}
nav ul li a::before {
position: absolute;
top: 100%;
left: 0px;
width: 100%;
padding: 4px 0px;
text-align: center;
line-height: 50px;
background: none repeat scroll 0% 0% #ffc400;
color: #FFF;
content: attr(data-hover);
transition: #ffc400 0.3s ease 0s;
transform: rotateX(-90 deg);
transform -origin: 50% 0px 0px;
}
Well the issue is that you're translating the link out of view so it cannot be clicked:
nav ul li a:hover {
background: #e9e9e9;
color: #000;
transform: rotateX(90deg) translateY(-22px);
}
The dead simple solution to this problem would be simply put an a element around the li element and change the current a element to a div, like so:
This way, the div and li elements that are being translated and rotated are surrounded by the clickable link.
<a href="#">
<li>
<div data-hover="Forums">Forums</div>
</li>
</a>
CSS:
* {
box-sizing: border-box;
}
nav {
background: #e9e9e9;
margin: -1rem 0rem;
z-index: 0;
}
nav ul {
list-style: none;
}
nav ul li {
display: inline-block;
text-transform: uppercase;
font-size: 1.5rem;
letter-spacing: 0.05rem;
}
nav ul li div {
display: inline-block;
padding: 1rem;
color: #000;
text-decoration: none;
transition: transform 0.3s ease 0s;
transform-origin: 50% 0px 0px;
transform-style: preserve-3d;
}
nav ul li div.current {
color: #ffc400;
}
nav ul li div:hover {
background: #e9e9e9;
color: #000;
transform: rotateX(90deg) translateY(-22px);
}
nav ul li div::before {
position: absolute;
top: 100%;
left: 0px;
width: 100%;
padding: 4px 0px;
text-align: center;
line-height: 50px;
background: none repeat scroll 0% 0% #ffc400;
color: #FFF;
content: attr(data-hover);
transition: #ffc400 0.3s ease 0s;
transform: rotateX(-90deg);
transform-origin: 50% 0px 0px;
}
And then adding a element styling to make everything work out:
nav ul a {
text-decoration: none;
}
Here's the updated pen.