Coloring every second sub-layer in CSS - javascript

I'm working on a whiteboard app that included hierarchy.
So my question is: How can I color every second sub-layer in CSS (or if needed js)?
Example stying
ul {
width: 256px;
min-height: 64px;
padding: 16px 0 16px 16px;
background-color: blue;
}
/*FOLLOWING SHALL BE REPLACED BY AN SELECTOR OR JS-ALGORITHM*/
div>ul>ul,
div>ul>ul>ul>ul,
div>ul>ul>ul>ul>ul>ul,
div>ul>ul>ul>ul>ul>ul>ul>ul {
background-color: red;
}
<div>
<ul>
<ul>
<ul>
<ul>
<ul>
<ul>
</ul>
</ul>
</ul>
</ul>
</ul>
</ul>
</div>
What I aim to color are the divs in line 2 and 4 (and so on: 6, 8, 10,... if I would work with more sub-layers)

There is no CSS selector for that. You can however achieve it with a recursive function in JavaScript (jQuery):
colorList($('div > ul'));
function colorList($ul) {
$ul.css({'backgroundColor': 'red'});
var $nextElement = $ul.find('> ul > ul');
if($nextElement.length) {
colorList($nextElement);
}
}

Related

jQuery sortable onDrop event freezes the page

I'm using jQuery Sortable library to create rearrangeable nested <ol> elements (do not confuse with jQuery UI sortable), when i try to execute code (console.log) in the onDrop event, the page freezes, and the dragged <li> element become transparent and floats on the page over the others elements (similar to position: absolute and opacity: 0.5)
Working example: https://johnny.github.io/jquery-sortable/#features
My code: http://jsfiddle.net/xdjn2wqp/2/
I wasn't getting a page freeze when testing your code, but the element that was dragged never got the .dragged class removed from it after dropping. Maybe you meant it appeared to freeze.
Either way when executing your code you get an error on the console
Uncaught TypeError: Cannot read property 'group' of undefined
And looking at the code, the _super method is defined to have up to 4 arguments, but looks like it requires just 2
http://johnny.github.io/jquery-sortable/js/jquery-sortable-min.js
onDrop: function(a, b, c, e) {
a.removeClass(b.group.options.draggedClass).removeAttr("style");
d("body").removeClass(b.group.options.bodyClass)
},
Non-minified version
http://johnny.github.io/jquery-sortable/js/jquery-sortable.js
onDrop: function ($item, container, _super, event) {
$item.removeClass(container.group.options.draggedClass).removeAttr("style")
$("body").removeClass(container.group.options.bodyClass)
},
You however only pass 1, item. And from the documentation page all the examples that use _super() use two arguments, the item and then the container
_super(item,container)
So once you pass in container as well, the problem not longer exists
$(".placeholder-children").droppable({
drop: function(event, ui) {
alert('dropped');
}
});
$(function() {
$("ol.tree").sortable({
group: 'serialization',
onDrop: function(item, container, _super) {
alert("a");
container.el.removeClass("active")
_super(item, container)
}
});
})
body.dragging,
body.dragging * {
cursor: move !important;
}
.dragged {
position: absolute;
opacity: 0.5;
z-index: 2000;
}
ol.tree {
background-color: #FFF;
margin: 10px;
padding: 10px;
}
ol {
list-style-type: none;
list-style: none;
}
ol li {
background: none repeat scroll 0 0 #eeeeee;
border: 1px solid #cccccc;
color: #0088cc;
display: block;
margin: 5px;
padding: 5px;
line-height: 18px;
}
<script type="text/javascript" src="//code.jquery.com/jquery-1.9.1.js"></script>
<script type="text/javascript" src="//code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<link rel="stylesheet" type="text/css" href="//code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css">
<script src="https://johnny.github.io/jquery-sortable/js/jquery-sortable-min.js"></script>
<ol class="tree serialization">
<li class="placeholder-children">First
<ol></ol>
</li>
<li class="placeholder-children">Second
<ol></ol>
</li>
<li class="placeholder-children">Third
<ol>
<li class="placeholder-children">First</li>
<li class="placeholder-children">Second</li>
<li class="placeholder-children">Third
<ol>
<li class="placeholder-children">First</li>
<li class="placeholder-children">Second</li>
</ol>
<ol>
<li class="placeholder-children">First</li>
<li class="placeholder-children">Second</li>
</ol>
</li>
</ol>
</li>
<li class="placeholder-children">Fourth</li>
<li class="placeholder-children">Fifth</li>
<li class="placeholder-children">Sixth</li>
</ol>

making a custom css rule

Is it possible to make a custom rule in Css as #media
I have a parent class and need to make changes depended on this class as
<div class="parentGreen">
<ul class="ul1">
<li>1</li>
<li>2</li>
</ul>
<ul class="ul2">
<li>1</li>
<li>2</li>
</ul>
</div>
so when i change the parentGreen the items inside their css changes too
#parentGreen{
ul{
direction: ltr
}
}
#parentYellow{
ul{
direction: rtl;
margin:10px;
}
}
Compiled version on this link is what you want.
Do you hear about less? Try searching about it. Less is better choice for creating nested css. You can write like this:
.parent {
.child1 {
color: blue;
}
.child2 {
color: blue;
}
}
Look this link.
This should work...
.parentGreen ul {
direction: ltr
}
.parentYellow ul {
direction: rtl;
margin:10px;
}

Unwanted space and arrow in accordion menu

I am creating a vertical accordion menu. Here is code what I had done so far. Two problems I am facing.
There is unwanted space between border and menu. It is for all li elements i.e for menu and sub menu items also.
And arrow is showing for submenu also after having following code
#menunav li > a:only-child:before { content: '';}
I trying to put arrow image for menu that having sub menus. e.g. Item 1 is having sub menus so Item 1 should have arrow not its sub menus items. And also if I have Sub-Item 1 a of Item 1, sub menus like below:
<li>Item 1
<ul>
<li>Sub-Item 1 a
<ul>
<li>Sub-Item 1 aa</li>
<li>Sub-Item 1 bb</li>
<li>Sub-Item 1 cc</li>
</ul>
</li>
<li>Sub-Item 1 b</li>
<li>Sub-Item 1 c</li>
</ul>
</li>
Then Item 1 and Sub-Item 1 a will have arrow etc.
I am not able to remove that space and putting arrow for menu that having submenu.
Can someone please suggest what should I change in jquery and css so that I can get that properly working?
CSS
#menunav{padding:0}
since we need to clear the default style of the ul element
Set #menunav, ul into li padding to 0
#menunav, #menunav ul {
padding: 0;
}
Or just reset the padding:
* {
padding: 0
}
Demo
Update
If you want to remove submenu arrow, do this:
Example:
#menunav li ul li a:before {
background: none;
}
updated demo: http://jsfiddle.net/jpcb7w5y/10/
Try this.
CSS:
#menunav {
padding: 0px;
}
#menunav li ul {
padding: 0px;
}
I think your <ul> has its own padding. Hope this helps.
Edited:
DEMO
I you want that the arrows only appears to the main menu that have the sub menu, I have this quick solution for that. Why not try putting some class on the <a> for the main menu. Hope this works.
Instead of:
#menunav li a:before {
content: "";
display: block;
background: url("http://transparency.perkinswill.com/content/images/right-arrow.png") no-repeat;
width: 20px;
height: 20px;
float: left;
margin: 0 6px 0 0;
}
Why not:
#menunav .main:before {
content: "";
display: block;
background: url("http://transparency.perkinswill.com/content/images/right-arrow.png") no-repeat;
width: 20px;
height: 20px;
float: left;
margin: 0 6px 0 0;
}

Trigger completely separate div based on hover of other div

Is it possible to trigger changes to CSS of an element that is completely unrelated to the hovered div?
I have a CSS hover effect on a dropdown menu, that I also want to trigger the opacity of a div right at the bottom of the page to create a background overlay effect.
This is the CSS I'm using:
#overlay {
background:rgba(0,0,0,0.5);
position:absolute;
top:120px;
left:0;
z-index:0;
height:120%;
width:100%;
visibility:hidden;
opacity:0;
}
#menu-main-menu li.menu-parent-item:hover ul.sub-menu,
#menu-main-menu li.menu-parent-item:hover #overlay {
visibility:visible;
opacity:1;
}
The hover of the sub menu works fine, but the div #overlay is right at the bottom of the page, and doesn't get called when it's hovered.
I've tried all kinds of alternatives such as :hover > #overlay, :hover + #overlay, but nothing seems to trigger it. I also can't seem to find a definitive answer to the question.
Is it possible?
Yes. You can load this style in a php file and then use jQuery to apply the css when your div has been hovered on.
No there is no way to select parent element in css and that means that you cannot move up in hierarchy.
<ul class="hover-parent">
<li></li>
</ul>
<div>Something here</div>
<div class="target"></div>
From this point :
.hover-parent li:hover you cannot go up (to ul or div).
Selectors which you tried to use are "next":
A>B - This will select only direct B children of A
A+B This will select B immediately preceded by A
Here you can find W3C documentation of CSS selector
http://www.w3.org/TR/CSS2/selector.html#adjacent-selectors
And demos:
http://code.tutsplus.com/tutorials/the-30-css-selectors-you-must-memorize--net-16048
Notice that it will be really confusing for user that different part off app/page is changing when he is hovering something else. Bad UX idea.
You're going to have to use JavaScript to do this.
Your posted selector #menu-main-menu li.menu-parent-item:hover #overlay is looking for #overlay somewhere inside of an ancestor element of li.menu-parent-item that is somewhere inside of an ancestor element with an id of #menu-main-menu.
Using the child selector > will not work as the overlay element is not a child of the list element you're hovering in your menu from what you have described and from comment responses.
As #Paulie_D has pointed out the two target elements, the element to be hovered and the overlay element, need to adjacent siblings to use the sibling selector +. From what you have described and the comment responses they are not adjacent siblings.
I have setup a basic example for you using jQuery. This example displays the overlay as long as you are hovering any element in the .main-menu element.
HTML
<ul class="main-menu">
<li>Item One</li>
<li>Item Two</li>
<li>Item Three
<ul class="sub-menu">
<li>Sub Item One</li>
<li>Sub Item Two</li>
<li>Sub Item Three</li>
<li>Sub Item Four</li>
<li>Sub Item Five</li>
</ul>
</li>
</ul>
<main>
Content here.
</main>
<footer>
<div class="overlay">This is my overlay.</div>
</footer>
CSS
body {
margin: 25px auto;
width: 500px;
}
ul,
li {
margin: 0;
padding: 0;
}
main {
min-height: 300px;
}
footer,
.overlay {
height: 50px;
}
footer {
position: realative;
background-color: yellow;
}
.main-menu {
list-style: none;
height: 50px;
}
.main-menu > li {
float: left;
padding: 0 10px;
position: relative;
}
.main-menu > li:hover .sub-menu {
display: block;
}
.sub-menu {
display: none;
list-style: none;
position: absolute;
left: 10px;
width: 150px;
}
.overlay {
display: none;
text-align: center;
}
jQuery
$overlay = $('.overlay');
$('.main-menu > li').hover(
// when hovered
function() {
$overlay.css('display','block');
},
// when NOT hovered
function() {
$overlay.css('display','none');
}
);
jsFiddle: http://jsfiddle.net/ednf2pzq/
Edit
You could simplify the jQuery hover selector to .main-menu.
jQuery
$('.main-menu > li').hover(
// same code as before
);
jsFiddle: http://jsfiddle.net/ednf2pzq/1/

How can I apply a background-color to several elements on hover?

I have a few lists that are displayed as inline-blocks, creating the illusion of rows. Unlike tables, I cannot format rows straightforwardly. I want to apply a background color to each < li > in the row when one is hovered over. Is this possible through CSS and names/IDs?
Thanks.
Mike
CLARIFICATION: After reading the answers, I realized my question was unclear. I have 3 lists, side by side, so the first < li > in each list would represent the first row. The second < li > in each list would be the second row. And so on.
Cross-browser support with jQuery:
CSS:
li:hover { background-color: #F00 }
And for IE6 -- since it does not support the :hover pseudo-class on anything but <a> elements -- you serve it the following in your IE6-specific style sheets and script:
CSS:
li.hover { background-color: #F00 }
JS:
$("li").hover(
function() {
$(this).addClass("hover");
},
function() {
$(this).removeClass("hover");
}
);
Not sure if I understand correctly, but this fairly simple solution should do the trick:
li:hover {
background-color: pink;
}
Some browsers do not support the hover pseudo class though.
If you want to apply a style to all child elements of a specific <ul>, you can use bigmattyh's approach but set the class on the <ul> instead of the <li>.
Then, add a CSS style such as this:
.hover li { /* some styles */ }
Using this approach you can apply styles to all of the child <li> elements, but you will only need event handlers in the parent <ul>, making your code run faster.
I would simplifying things and reorganize your HTML so that each UL is a row instead of a column.
<html>
<head>
<style>
ul { clear: both; }
ul li {
float: left;
list-style: none;
padding: 5px 10px;
border: 1px solid white; }
.hover { background-color: red; }
</style>
</head>
<body>
<div id='list-container'>
<ul class="hover">
<li>a</li>
<li>b</li>
<li>c</li>
</ul>
<ul>
<li>a</li>
<li>b</li>
<li>c</li>
</ul>
<ul>
<li>a</li>
<li>b</li>
<li>c</li>
</ul>
</div>
</body>
</html>
And the JS:
$(document).ready(function() {
var alterRow = function(container, class, toggleOn) {
$(container).children().each(function(i, node) {
if ( toggleOn ) {
$(node).addClass(class);
} else {
$(node).removeClass(class);
}
});
};
$("#list-container ul").each(function(i, node) {
$(node).hover(
function() { alterRow(node, "hover", true); },
function() { alterRow(node, "hover", false); }
);
});
});
You can see and edit it here: http://jsbin.com/ewijo

Categories