I'm trying to figure out how to position a flowchart built with ul list growing like a tree, from bottom-up.
It's a genealogical family tree. I've made it from top down using this great code here but I want the first element in the bottom, above it the parents and above it the grandparents and so on...
Here is the code:
HTML
<div class="tree">
<ul>
<li>
<div class="dados_membro">Me</div>
<ul>
<li>
<div class="dados_membro">Father</div>
<ul>
<li>
<div class="dados_membro">Grandfather</div>
</li>
<li>
<div class="dados_membro">Grandmother</div>
</li>
</ul>
</li>
<li>
<div class="dados_membro">Mother</div>
<ul>
<li>
<div class="dados_membro">Grandfather</div>
</li>
<li>
<div class="dados_membro">Grandmother</div>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
CSS
.tree ul {
padding-top: 20px;
position: relative;
}
.tree li {
float: left;
text-align: center;
list-style-type: none;
position: relative;
padding: 39px 5px 0 5px;
}
.dados_membro {
border: 1px solid;
border-radius: 20px;
width: 300px;
margin: auto;
text-align:left;
padding:10px
}
I'm testing some rules in this fiddle and could position the first node "Me" in the bottom and the other ones up with the CSS bellow, but all the nodes in the same level (parents, grandparents and so on..) get pilled up.
.tree ul {
position: absolute;
bottom:0;
}
.tree ul li ul{
position:relative;
}
.tree li {
float: right;
text-align: center;
list-style-type: none;
position: relative;
padding: 20px 5px 0 5px;
margin-top:-120px
}
.dados_membro {
border: 1px solid;
border-radius: 5px;
width: 100px;
margin: auto;
text-align:left;
padding:10px
}
I don't know how big will the tree grow up nor if all the nodes will have elements. Can't use javascript for this. Any ideas?
You could change the order of the elements using the flexbox property flex-direction: column-reverse, if that is an option for your project (see compatibility table).
To revert the order of the list I gave the main container position: absolute with bottom:0, the <ul>s a position:relative and all <li>s position:absolute with bottom:50px, except for the first level that I want to be in the bottom of the container.
This way every <li> is positioned 50px above its parent <ul> that has relative position.
One last tweak to achieve the tree style was adding a class for female and male parents in order to position each one in the left and in the right above its child node. Since I'm generating this tree dinamically I can count how many levels does the tree has and calculate the distance between father/mother nodes. If I could not control the html dinamically, I would need to use javascript to count the nodes and apply the css rules on the fly (maybe I will do ti in the future, just to animate the tree generation).
The new code is here
HTML
<div class="tree">
<ul>
<li>
<div class="dados_membro">Me</div>
<ul>
<li class="f1">
<div class="dados_membro">Father</div>
<ul>
<li class="f2">
<div class="dados_membro">Grandfather f</div>
</li>
<li class="m2">
<div class="dados_membro">Grandmotherf </div>
</li>
</ul>
</li>
<li class="m1">
<div class="dados_membro">Mother</div>
<ul>
<li class="f2">
<div class="dados_membro">Grandfather m</div>
</li>
<li class="m2">
<div class="dados_membro">Grandmother m</div>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
CSS
.tree {
position:absolute;
bottom: 0;
left:300px
}
.tree ul {
position: relative;
list-style:none;
}
.tree ul li ul li{
position: absolute;
bottom: 50px;
}
.f1{
left:-150px;
}
.m1 {
left:150px;
}
.f2{
left:-80px;
}
.m2 {
left:80px;
}
.dados_membro {
border: 1px solid;
border-radius: 5px;
width: 100px;
margin: auto;
text-align:left;
padding:10px
}
Related
I'm trying to make a basic navigation bar where a child dropdown appears when hovering over a list item. I want to position this dropdown starting at the right most edge of the list item I am hovering over, but I want it this dropdown be able to scale bigger than the list item you're hovering over.
The trouble is that when I position the parent relative, the dropdown's width is constricted to the width of the list item you're hovering over, when I remove postion relative I lose the ability to position it the way I want it.
When the parent List item doesn't have position relative it looks like this:
But I want the right edge of that dropdown to align with the right side of the list item I'm hovering on. When I add position relative to the list items, the width of the dropdown is contsrained like this:
The markup looks like follows:
<nav>
<ul class="outer-list">
<li>
<a>
Work
</a>
<ul class="inner-list">
<li>Sub1</li>
<li>Sub2</li>
<li>Sub3</li>
</ul>
</li>
</ul>
<ul class="outer-list">
<li>
<a>
Contact
</a>
</li>
</ul>
<ul class="outer-list">
<li>
<a>
Helpdesk
</a>
<ul class="inner-list">
<li>Sub1</li>
<li>Sub2</li>
<li>Sub3</li>
</ul>
</li>
</ul>
<ul class="outer-list">
<li>
<a>
Subscriptions
</a>
<ul class="inner-list">
<li>Sub1</li>
<li>Sub2</li>
<li>Sub3</li>
</ul>
</li>
</ul>
I am not in charge of the markup, but if it needs to change to allow for a solution that is fine.
My CSS is as follows:
.outer-list{
.dropdown{
padding-right: 20px;
a{
color: black;
text-decoration: none;
position: relative;
.icon-dropdown{
position: absolute;
display: inline-block;
width: 6px;
height: 4px;
background-image: url('./Assets/BlueArrowIcon.svg');
background-size: cover;
background-position: center;
top: 50%;
right: -11px;
transform: translateY(-50%)
}
}
.inner-list{
padding: 25px 20px;
display: none;
position: absolute;
background-color: $color-white;
box-shadow: 5px 0px 50px rgba(0,0,0,0.16);
z-index: 1;
max-width: 310px;
li{
margin-bottom: 20px;
&:hover{
a{
color: $color-dark-red;
}
}
}
}
&:hover{
a{
color: $color-blue;
}
.inner-list{
display: block;
a{
color: black;
}
}
}
}
&:last-of-type{
.dropdown{
padding-right: 0px;
}
}
}
If anyone could help me that would be much appreciated.
I have the following code to show a division on hover. It is initially hidden and i'm trying to show one division on hover of another element.
.topNav {
padding: 1px 15%;
background: #006cb4;
color: white;
}
.mainMenu {
list-style-type: none;
}
.mainMenu li {
display: inline-block;
padding: 3px 15px;
font-size: 20px;
}
.mainMenu li a {
text-decoration: none;
color: white;
}
#item1 {
display: block;
}
#item1:hover #item1detail {
background: #444;
visibility: visible;
}
#item1detail {
position: absolute;
top: 152px;
left: 250px;
background: #ccc;
width: 750px;
height: 400px;
border: solid 1px black;
border-radius: 0 0 10px 10px;
visibility: hidden;
}
<div class="topNav">
<ul class="mainMenu">
<li><a id="item1" href=""> item 1</a>
</li>
<li> item 3
</li>
<li> item 4
</li>
<li> item 5
</li>
<li> item 6
</li>
<li> item 7
</li>
<li> item 8
</li>
<li> item 9
</li>
</ul>
<div id="item1detail">
Some random content
</div>
</div>
on hover of the list item item1 i want to show the division itemdetail. The above code is not working. What am i doing wrong?
As I see it the only solution to display the given div without touching the HTML would be Javascript... As the others suggested already...
BUT... there's a solution with one slight change to your HTML and CSS each.
The main problem is this CSS-selector:
#item1:hover #item1detail
which would translate to "id item1detail INSIDE of an hovered id item1".
You can fix this by placing the div inside of the li and change the selector to:
#item1:hover + #item1detail
Since the div is positioned absolute anyway it doesn't make a visual difference... at least for your snippet...
Updated version of your snippet:
.topNav
{
padding: 1px 15%;
background: #006cb4;
color: white;
}
.mainMenu
{
list-style-type: none;
}
.mainMenu li
{
display: inline-block;
padding: 3px 15px;
font-size: 20px;
}
.mainMenu li a
{
text-decoration: none;
color: white;
}
#item1
{
display: block;
}
#item1:hover + #item1detail
{
background: #444;
visibility: visible;
}
#item1detail
{
position: absolute;
top: 152px;
left: 250px;background: #ccc;
width: 750px;
height: 400px;
border:solid 1px black;
border-radius: 0 0 10px 10px;
visibility: hidden;
}
<div class="topNav">
<ul class="mainMenu">
<li >
<a id="item1" href=""> item 1</a>
<div id="item1detail">
Some random content
</div>
</li>
<li> item 3</li>
<li> item 4</li>
<li> item 5</li>
<li> item 6</li>
<li> item 7</li>
<li> item 8</li>
<li> item 9</li>
</ul>
</div>
You'll have to use javascript
<script>
function myFunction() {
if (document.getElementById("item1detail").hidden==false){
document.getElementById("item1detail").hidden = true;
}else{
document.getElementById("item1detail").hidden = false;
}
}
</script>
and
<div class="topNav">
<ul class="mainMenu">
<li><a id="item1" onhover="myFunction()" href=""> item 1</a>
</li>
<li> item 3
</li>
<li> item 4
</li>
<li> item 5
</li>
<li> item 6
</li>
<li> item 7
</li>
<li> item 8
</li>
<li> item 9
</li>
</ul>
<div id="item1detail">
Some random content
</div>
</div>
I would do that using jQuery.
$('#item1').hover(function(){
$('#item1detail').show();
}, function(){
$('#item1detail').hide();
});
The reason your CSS isn't working is because you're using this selector:
#item1:hover #item1detail
Which selects the element with id #item1detail occurring within the element with id #item1, if the #item1 element is hovered.
In your current markup, #item1detail is outside #item1, and so does not match the selector. Moving #item1detail should get you the behavior you want. (And there will probably be some layout work to do from that point.)
The #item1detail element is not a sibling of the #item1 element, so that is why the #item1:hover #item1detail CSS rule does not apply as you expect it to.
I believe if this is to work with CSS only (not JavaScript), then you will have to make #item1detail a sibling of #item1.
I may seem really silly or outright wrong in the way I code. However, when I create a drop down menu in CSS the new li elements get pushed to the other side of the page and not in the container box. How would I fix this?
Here is the code:
<nav>
<div class="wrapper">
<div class="brand">
<img class="UKLogo" src="images/logo.png" alt="">
</div> <!-- brand -->
<div class="navigation">
<ul class="nav-ul">
<li> HOME </li>
<li> ABOUT </li>
<a href="#">
<li class="course-li">
COURSES
<ul class="drop-down">
<li class="list-item"> Driver CPC </li>
<li> First Aid </li>
<li> Other </li>
</ul>
</li>
<li> CONTACT </li>
<!-- <li> TESTOMONIALS </li> -->
<!-- <li> FAQs </li> -->
</ul>
</div> <!-- Navigation -->
</div> <!-- Wrapper -->
</nav>
nav {
margin: 0px;
padding: 0px;
height: 75px;
background-color: #FFF;
}
.brand {
margin: auto;
width: 960px;
}
.company-name {
padding: 0px;
margin: 0px;
}
.UKLogo {
padding: 0px;
margin: 0px;
position: relative;
top: 11px;
}
.navigation ul li {
display: inline-block;
margin: 10px;
position: relative;
left: 380px;
top: -46px;
}
.navigation ul a {
color: black;
margin-left: 40px;
text-decoration: none;
font-family: Lato;
font-weight: 300;
}
.navigation ul a:hover {
color: #169ec5;
font-weight: 300;
}
.course-li:hover .drop-down {
left: 0px;
}
.drop-down {
position: absolute;
left: -5px;
z-index: 1;
background-color: white;
left: -9999px;
}
Thank you ever so much for looking and helping. Always open to criticism whether its the way I code or anything else.
Here is a JSFiddle https://jsfiddle.net/vj41qLts/
Many Thanks!
You need to declare a position in the parent, for the child to reside in. An element with position: absolute; will position itself to the first parent with position: relative;. If there is no parent with position: relative;, it will use the browser window instead.
See fix example here: https://jsfiddle.net/vj41qLts/1/
I think there are two thing you need to change:
ul li will select everything li in the navigation even the dropdown, ul>li will only select the immediate child, instead of running down the nested elements.
you need to add position:relative; in your dropdown's parent.
One of the first issues I see is the fact that your markup for your main links isn't setup correctly. Following a structure more link the below should give make it work the way you want it to:
<nav>
<ul>
<li><a href="#">Home<a></li>
<li><a href="#">About<a></li>
<li>
<a href="#">Courses<a>
<div>
<ul>
<li>A link</li>
<li>A link</li>
</ul>
</div>
</li>
</ul>
</nav>
Then use CSS or JS to control showing and hiding the dropdown of links.
I am trying to customize a funnel chart on the basis of data that I have rendered through database on page.
All works well except css rendering for chart.
<ul id="funnel-cht">
<li style="height:70px;width:50%;background-color:yellow">pendora</li>
<li style="height:70px;width:40%;background-color:#98bf26">pending</li>
<li style="height:70px;width:30%;background-color:orange">pen</li>
<li style="height:70px;width:20%;background-color:#c10000">Test</li>
</ul>
Here is what it looks like right now-
http://jsfiddle.net/m74ets8v/1/
I want to style it according to actual looking funnel chart, for an example-
How would i be styling this chart to make sense for me.
.funnel_outer{width:420px;float: left;position: relative;padding:0 10%;}
.funnel_outer *{box-sizing:border-box}
.funnel_outer ul{margin:0;padding:0;}
.funnel_outer ul li{float: left;position: relative;margin:2px 0;height: 50px;clear: both;text-align: center;width:100%;list-style:none}
.funnel_outer li span{ border-top-width: 50px;border-top-style: solid; border-left: 25px solid transparent; border-right:25px solid transparent; height: 0;display: inline-block;vertical-align: middle; }
.funnel_step_1 span{width:100%;border-top-color: #8080b6;}
.funnel_step_2 span{width:calc(100% - 50px);border-top-color: #669966}
.funnel_step_3 span{width:calc(100% - 100px);border-top-color: #a27417}
.funnel_step_4 span{width:calc(100% - 150px);border-top-color: #ff66cc}
.funnel_step_5 span{width:calc(100% - 200px);border-top-color: #0099ff}
.funnel_step_6 span{width:calc(100% - 250px);border-top-color: #027002}
.funnel_step_7 span{width:calc(100% - 300px);border-top-color: #ff0000;}
.funnel_outer ul li:last-child span{border-left: 0;border-right: 0;border-top-width: 40px;}
.funnel_outer ul li.not_last span{border-left: 5px solid transparent;border-right:5px solid transparent;border-top-width:50px;}
.funnel_outer ul li span p{margin-top: -30px;color:#fff;font-weight: bold;text-align: center;}
<div class="funnel_outer">
<ul>
<li class="funnel_step_1"><span><p>1</p></span></li>
<li class="funnel_step_2"><span><p>2</p></span> </li>
<li class="funnel_step_3"><span><p>3</p></span></li>
<li class="funnel_step_4"><span><p>4</p></span></li>
<li class="funnel_step_5"><span><p>5</p></span></li>
<li class="funnel_step_6"><span><p>6</p></span></li>
<li class="funnel_step_7"><span><p>7</p></span></li>
</ul>
</div>
The secret is to use margin: 0 auto for the lis. Setting the automatic margin calculation for the left/right dimension will center a block element horizontally. (Unfortunately, this technique doesn't work for vertical centering, but that's a different story.)
Here's your code, slightly modified, in a working example:
ul, li { margin: 0; padding: 0; list-style: none; }
ul { width: 400px; }
li { height: 70px; margin: 0 auto; }
/* NOTE: nth-child would be the better way to assign CSS to a set of
uniform elements than one class per li, but let's keep it simple for now */
li.li1 { width: 50%; background-color: yellow; }
li.li2 { width: 40%; background-color: #98bf26; }
li.li3 { width: 30%; background-color: orange; }
li.li4 { width: 20%; background-color: #c10000; }
<ul>
<li class='li1'>pendora</li>
<li class='li2'>pending</li>
<li class='li3'>pen</li>
<li class='li4'>Test</li>
</ul>
By the way, as already noted in the comments: In order to have actual trapezoids, you would (as far as I know) need to use SVG, and of course appropriate fallbacks for browser that don't support it.
If, as i read from comments, you just need to center the <li> elements you can set the an auto margin.
#funnel-cht>li
{
display:block;
margin:0 auto;
}
I am trying to make a navigation bar with a four columns submenus. I coded most of things, but when I creating the submenu I found the problem.
This is my HTML:
<div id="navigation">
<ul>
<li class="current">
Home
</li>
<li class="sub-menu">
Our Products
<div class="subnav product">
<div class="content">
<div class="col">
<ul>
<li class="one">
Main Menu Item
</li>
<li class="one">
Main Menu Item
</li>
<li class="one">
Main Menu Item
</li>
</ul>
</div>
<div class="col">
<ul>
<li class="two">
<img src="" />
Promoting Peace in the Niger Delta
</li>
<li class="three">
<img src="" />
Promoting Peace in the Niger Delta
</li>
<li class="four">
<img src="" />
Promoting Peace in the Niger Delta
</li>
<li class="five">
<img src="" />
Promoting Peace in the Niger Delta
</li>
</ul>
</div>
</div>
</div>
</li>
<li class="">
Service Maintenance
</li>
<li class="sub-menu">
Frequently Ask Questions
<li class="sub-menu">
Our Products
<div class="subnav product">
<div class="content">
<div class="col">
<ul>
<li class="one">
Main Sub Item
</li>
<li class="one">
Main Sub Item
</li>
<li class="one">
Main Sub Item
</li>
</ul>
</div>
</div>
</div>
</li>
</ul>
</div>
Hope somebody will help me out.
Thank you.
The problem is the container width is defined at 300px
#navigation ul li > div.product {
width: 300px;
}
And its child elements are taking up 100% of that space. So you need to make sure they have room to float left.
#navigation div.col {
float: left;
height:200px;
width: 25%;
}
Hopefully that helps with your question.
Fiddle
Check this http://jsfiddle.net/qtvVK/11/embedded/result/.
I made some changes to your markup and used display:inline-block; instead of floating elements
Relevant CSS syles
/* Dropdown styles */
#navigation ul > li > ul.sub-menu {
display: none;
position:absolute;
padding:10px 0;
background:#fff;
border: 1px solid #DDDCDC;
top: 24px;
z-index: 1;
}
/* Show dropdown when hover */
#navigation ul > li:hover > ul.sub-menu {
display:block;
}
.row {
width:auto;
white-space: nowrap;
}
.col {
display: inline-block;
vertical-align: top;
padding: 0 10px;
}
i suggest using jQuery.
it has simple function called slideDown().
Here is a link to a good tutorial.
You should do like so: First hide your menu when script starts:
$("#idOfDropDownMenu").hide();
And command to drop menu down when mouse enters button and slide up when it leaves it:
$("#idOfButton").hover(function(){ //function that fires when mouse enters
$("#idOfDropDownMenu").slideDown();
}, function() { //function that fires when mouse leaves
$("#idOfDropDownMenu").slideUp();
}
Instead of using IDs you can use any CSS selector.
I hope this helps with your question.
css
ul li ul
{
display: none;
position: fixed;
margin-left: 191px;
margin-top: -37px;
}
ul li:hover ul
{
display: block;
}
ul li a:hover
{
color: #fff;
background: #939393;
border-radius:20px;
}
ul li a
{
display: block;
padding: 10px 10px;
color: #333;
background: #f2f2f2;
text-decoration: none;
}
ul
{
background: #f2f2f2;
list-style:none;
padding-left: 1px;
width: 194px;
text-align: center;
}
html
<ul>
<li>Home</li>
<li>
About
<ul>
<li>About Me
<li>About Site
</ul>
</li>
<li>Contact</li>
</ul>