How to get a tree in HTML using pure CSS - javascript

I am trying to follow this tutorial and here's my code so far.
The end of the tutorial shows that the last nodes in a branch won't have any vertical bars after it. But I couldn't get it working that way!. Any ideas if I am doing something wrong, or maybe the tutorial is missing something!
I tried even the :last-child pseudo class as shown in the tutorial, but got the same result.

Here's a try using only pseudo-elements and borders:
ul, li{
position: relative;
}
/* chop off overflowing lines */
ul{
overflow: hidden;
}
li::before, li::after{
content: '';
position: absolute;
left: 0;
}
/* horizontal line on inner list items */
li::before{
border-top: 1px solid #333;
top: 10px;
width: 10px;
height: 0;
}
/* vertical line on list items */
li::after{
border-left: 1px solid #333;
height: 100%;
width: 0px;
top: -10px;
}
/* lower line on list items from the first level
because they don't have parents */
.tree > li::after{
top: 10px;
}
/* hide line from the last of the first level list items */
.tree > li:last-child::after{
display:none;
}
demo (edited)

Sadly, the pseudo-class is defined in the upcoming CSS3 specification and at the moment few web browsers support it.
It's written at the end of the tutorial. Maybe that's the reason it's not working.

I believe I've fixed it: https://github.com/gurjeet/CSSTree/pull/1
I modified the CSS to remove the background and changed margin to padding.
ul.tree, ul.tree ul {
list-style-type: none;
margin:0;
padding:0;
}
ul.tree ul {
padding-left: 1em;
background: url(vline.png) repeat-y;
}
ul.tree li {
margin:0;
padding: 0 1.2em;
line-height: 20px;
background: url(node.png) no-repeat;
color: #369;
font-weight: bold;
}
/* The #fff color background is to hide the previous background image*/
ul.tree li.last {
background: #fff url(lastnode.png) no-repeat;
}
ul.tree ul:last-child {
background: none;
}

Thank you guys, helpful answers which made me read some more, and finally I read this article and removed all dependency on JavaScript, and used the nth-last-of-type pseudo-selector to apply the special background to the last li items in a list (ignoring the ul that comes after the last li).
The final code is here. I am going to accept my own answer, unless someone points out some problem with it. (I don't think compatibility with older browsers matters to me at this stage.)
Thanks to #Aram for the answer. #OneTrickPony, your answer went over the head of this noob :) I am sure it does the right thing, but it's a bit too complicated for me.
<style type="text/css">
/* ul[class=tree] and every ul under it loses all alignment, and bullet
* style.
*/
ul.tree, ul.tree ul {
list-style-type: none;
margin:0;
padding:0;
}
/* Every ul under ul[class=tree] gets an indent of 1em, and a background
* image (vertical line) applied to all nodes under it (repeat-y)
*/
ul.tree ul {
padding-left: 1em;
background: url(vline.png) repeat-y;
}
/* ... except the last ul child in every ul; so no vertical lines for
* the children of the last ul
*/
ul.tree ul:last-child {
background: none;
}
/* Every li under ul[class=tree]
* - gets styling to make it bold and blue, and indented.
* - gets a background image (tilted T), to denote that its a node
* - sets height to match the height of background image
*/
ul.tree li {
margin:0;
padding: 0 1.2em;
background: url(node.png) no-repeat;
line-height: 20px;
color: #369;
font-weight: bold;
}
/* The last li gets a different background image to denote it as the
* end of branch
*/
ul.tree li:nth-last-of-type(1) {
background: url(lastnode.png) no-repeat;
}

Related

hover element below other element possibly hovered

I have a problem with my css.
i have some element generated by javascript and when i hover them i display another element but i don't know why, the new element displayed is below the others generated element...
this is my css about this problem:
.hiddenTextjob
{
display:none;
background-color:#000;
color:#FFF;
width:170px;
z-index:2!important;
height:55px;
}
.ghost_for:hover > .hiddenTextjob
{
display: block;
background-color:#000;
color:#FFF;
width:170px;
margin-top:-55px;
z-index:1!important;
}
.ghost_for
{
border: 0;
position:absolute;
background-color:blue;
z-index:1!important;
}
.hiddenTextjob is below ghost_for but he must be above...
Thanks by advance
[EDIT] here a jsfiddle to illustrate:
https://jsfiddle.net/95jtx2oL/
when you hover a blue element sometine the black hover is above sometime he is below that make me mad...
.ghost_for:hover {
z-index: 2!important;
}
The above code is enough to fix the issue ^^ jdfiddle
The issue was because of the stacking of HTML. The lower elements will be higher if they are on the same index. So if you can raise the z-index of the hovered element, it's child element will be higher as well.
It looks a bit strange that you set z-index to 1 here.
.ghost_for:hover > .hiddenTextjob
{
display: block;
background-color:#000;
color:#FFF;
width:170px;
margin-top:-55px;
z-index:1!important;
}
The initial value of 2 seems correct. Try to remove z-index from the above code or set it to 2.
I am unsure of your HTML but try this if it works for you:
.hiddenTextjob {
display: none;
background-color: #000;
color: #fff;
width: 170px;
z-index: 2 !important;
height: 55px;
}
.ghost_for:hover > .hiddenTextjob {
display: block;
background-color: #000;
color: #fff;
width: 170px;
margin-top: -55px;
}
.ghost_for {
border: 0;
position: absolute;
background-color: blue;
z-index: -1;
}

Align nested element to top of div using nth-child property

I need to assign .dropdown .has-panel ul .dd-panel:nth-child(2) different top:x values but it seems my nth-child is not working correct as i may be doing something wrong.
fiddle sample http://jsfiddle.net/Ed9nk/4/
I need to align Level 3/ Grand Child menus at top of the container like level 2 /Child menus so that respective level3 me menus always show at top.
i added following css
/* has set top: -64px; manually so that Parent One > Child Menu> Grand Child align to top*/
.dropdown ul ul .dd-panel {
background: none repeat scroll 0 0 red;
border-left: 0px solid #30a784;
border-right: 0px solid #008438;
bottom: 0;
display: none;
font-size: 11px;
height: 100%;
left: 175px;
line-height: 15px;
min-height: 100px;
padding: 10px;
position: absolute;
text-align: justify;
top: -64px;
width: 400px;
}
.dropdown .has-panel ul .dd-panel:nth-child(2)
{
top: -64px;
background-color:green;
}
.dropdown .has-panel ul .dd-panel:nth-child(4)
{
top: -164px;
background-color:yellow !important;
}
My simple question is i always want Image & Text related to level 2 or level 3 menus to show up as top, i tried so many thing but nothing is working finally if thought of working with nth-child but i am not abel to get it right may be mixed up elements.
Based on your Image you have added in your question, I am going to give the solution. Update your CSS like below.
ul.nav > li > .dropdown.has-panel li:nth-child(3) > .dropdown.has-panel .dd-panel
{
margin-top: -90px;
background-color:green !important;
}
DEMO

How to draw the line for list element from the starting of div container?

The live example http://jsfiddle.net/vro0om/yhvnh/
I am trying to draw the line separating 2 li elemts in nested ul. But the line takes the width of the container ul and not the div containing the complete structure. In the mentioned example I have used nested ul but in my working using ng-repeat to obtain the same effect.
.unstyled {
padding-left: 24px;
}
.titleSeperator
{
background: black ;
margin-top: 0px;
margin-bottom: 0px;
height : 1px;
width:100%;
}
I think there is an easier way to do what you want.
First, remove all your .titleSeperator divs. Then, use the following CSS code for the parent ul:
ul.lines {
line-height: 1.4em;
background: linear-gradient(white 95%, black 5%);
background-size: 100% 1.4em;
background-origin: content-box;
}
The new fiddle : http://jsfiddle.net/yhvnh/2/
Some explanations for the CSS:
line-gradient allows to create a gradient starting with 95% of white and ending with 5% of black
background-size define the size of the gradient : width 100% and height 1.4em (should be the same as line-height)
background-origin specifies what the background-position property should be relative to
You can set position: relative; overflow: hidden; on topmost ul and make separators absolutely positioned
.titleSeperator {
background: black;
height : 1px;
width: 10000px;
position: absolute;
left: 0;
}
Demo: http://jsfiddle.net/yhvnh/3/
However Lucas proposed better approach, so use it if you can, you should avoid redundant HTML elements.
Variant 2
You can also use :before pseudo element instead of redundant .titleSeparator divs
.unstyled > li:before {
content:'';
background: black;
height : 1px;
width: 10000px;
position: absolute;
left: 0;
}
Demo: http://jsfiddle.net/yhvnh/4/

html - css block Width/Height

I have the following CSS code:
#nav {}
#nav a {
position: relative;
display: inline-block;
color: #F0F0F0;
width: 1em;
height: 2em;
line-height: 0.9em;
}
#nav a.icon:before { padding-right: 0;}
<nav id="nav">
<span>Home</span>
</nav>
But if the text is longer than 10 characters, it is automatically making a paragraph, making the text out of the original box. How can I prevent this?
Edit
All i want the background box in the screenshot to get bigger in width as the text is longer
http://prntscr.com/2cd973
if your aim is to display it all on the same line, you just need to remove width:1em; from #nav a
if you want to hide the text that is overflowing add overflow:hidden; to #nav a
if you want the a tag to adapt height and width to its content remove width:1em; and height:2em; from #nav a
You can display your content as a table-row. Then your links will be displayed as new columns in a table.
#nav {
display: table-row;
}
You can see the results on this fiddle.
Add this in #nav :
word-wrap:break-word;

Bug with inside responsive menu

I am beginner in JS.
I found wonderful example of responsive menu, and put code inside functions.php. Menu must works like here http://filamentgroup.com/examples/rwd-nav-patterns/ but i have the bug - dropdown menu shift to the right in my site when I use tablet mode.
I tried to include this menu in my site, based on Bootstrap http://b.pusku.com
UPDATE:
Part of the problem with the fiddle was that the space allotted for the logo image was too wide, so I added the following to correct that:
#logo > img {
width: 25px;
}
To get the dropdown to float left at all times, add:
.nav-menu .nav-primary {
float: left;
clear: none;
}
to the #media screen and (min-width: 910px) rule...
#media screen and (min-width: 910px) {
.nav-primary {
float: right;
clear: none;
}
.nav-menu .nav-primary {
float: left;
clear: none;
}
}
Once the navigation links collapse to a dropdown, they'll float left. The links will have an offset of 25px on the left because of the following rule in bootstrap.css (on line 728):
ul, ol {
padding: 0;
margin: 0 0 10px 25px; /*specifically this rule*/
}
You can override that, if you like, by adding margin-left: 0; to the .nav-primary ul rule:
.nav-primary ul {
border: 1px solid #e6e6e6;
margin-left: 0; /* add this to override the bootstrap.css rule*/
}
Finally, as the screen width narrows, the dropdown's width seems to stretch the entire width. If this is not a desired effect, add display: inline-block; to the .nav-primary rule:
.nav-primary {
clear: left;
margin: 0 0 2em;
display: inline-block;
}
I've also re-written the javascript that makes the "responsive" navigation collapse to a dropdown using more (appropriately named) variables so you may better understand why the script does what it does:
$(document).ready(function () {
'use strict';
$('.nav-primary')
// test the menu to see if all items fit horizontally
.bind('testfit', function () {
var nav = $(this),
navPrimaryTop = nav.offset().top, // top of div.nav-primary
navSkipNavTop = nav.prev().offset().top, // top of p containing a#main
topOfFirstLink = nav.find('li:first-child').offset().top, //top of "What We Done"
topOfLastLink = nav.find('li:last-child').offset().top, //top of "Contact Us"
navBelowSkipNav = navPrimaryTop > navSkipNavTop, //boolean indicating whether div.nav-primary is below the p containing a#main
lastLinkBelowFirstLink = topOfLastLink > topOfFirstLink, //boolean indicating whether "Contact Us" is below "What We Done"
displayAsMenu = navBelowSkipNav || lastLinkBelowFirstLink; // boolean indicating whether to collapse to a dropdown menu
$('body').removeClass('nav-menu');
if (displayAsMenu) {
$('body').addClass('nav-menu');
}
})
// toggle the menu items' visiblity
.find('h3').bind('click focus', function () {
$(this).parent().toggleClass('expanded');
});
// ...and update the nav on window events
$(window).bind('load resize orientationchange', function () {
$('.nav-primary').trigger('testfit');
});
});
Here's an updated fiddle demonstrating the basics: http://jsfiddle.net/DD7MC/1/
I did not override either the margin-left or the display in the updated fiddle.
ORIGINAL:
I think it's a CSS conflict between rwd-nav.css and bootstrap.css. Try changing the class definition for .nav-menu .nav-primary h3 in rwd-nav.css to:
.nav-menu .nav-primary h3 {
position: absolute;
top: -10px; /* <-- change this line */
left: auto;
right: 0;
display: block;
width: 4em;
height: 3.75em; /* <-- change this line */
background: #ccc url(img/icons.png) no-repeat -205px 45%;
text-indent: -999em;
cursor: pointer;
font-size: inherit; /* <-- add this line */
}
Also, your hosting provider is returning a 404 for url(img/icons.png). You may want to make sure that file exists.

Categories