CSS - hover one item and remove content of another item - html

I'm working with Wordpress menu where I have classic menu and item's submenus. When I hover some item which has children then submenu will show. The problem is when I have some current page then li class is current-submenu-item and has arrow in bottom of item. And when I hover another item which has submenu (children) I want to disappear that arrow in bottom of current item and when I unhover it then arrow will show again.
The current item's class is this:
li.current-submenu-item a:after {
position: absolute;
bottom: -25px;
left: 50%;
margin-left: -10px;
width: 20px;
content: url("http://elvis.zitnikcreative.cz/wp-content/themes/elvis_theme/img/menu_aktivni_sipka.png");
}
JsFiddle here.
I tried something like this:
li.menu-item-has-children:hover + .li.current-submenu-item a:after {
content:"";
}
But without result. How can I do that only with CSS?

Since the adjacency selector + (exactly like the general adjacency selector ~) works for next sibling only, you need to control this behaviour through the :hover state of your parent ul, e.g.
ul:hover li.current-submenu-item a:after {
content:"";
}
ul:hover li.current-submenu-item:hover a:after {
content:url("http://.../menu_aktivni_sipka.png");
}
So when you :hover the menu then hide the arrow unless you are also hovering the .current-submenu-item item
Example: http://jsfiddle.net/fozuu6hL/1/
As a side note, your example could work only when you hover the first list-item (as specified above) but you need to remove the extra . in front of li.

Related

Creating a CSS Inside Border on One Side

How can I produce the effect of a border on the inside of one side of my element?
My goal is to create a marker that indicates the currently selected item from a vertical list. Such as in the mockup below, where the 3rd item is selected:
Because this is a updatable state, which I'm setting by giving the li tag a class="active", I have been going down the path of the ::after pseudo-element.
The closest I have gotten is the following :
ul li::after {
background-color: #fbc123;
content: "";
float: right;
height: 40px;
position: absolute;
width: 5px; }
This is still putting the highlight on the outside of the 40px-by-40px box. How can I shift this, 5 pixels to the right?
I have create a jsFiddle, but it is behaving differently then what I see in my real code. In the jsFiddle the yellow lines remain on the left, instead of the aligning to the right.
http://jsfiddle.net/EvilClosetMonkey/m8A3e/
How can I create the effect of the 5px border on the right side only?
I think you can just try using border-right, set the relative position for the inner direct child and send them to the back using z-index like this:
ul > li.active {
border-right:5px solid yellow;
box-sizing:border-box;
}
ul > li.active > * {
position:relative;
z-index:-3;
}
You don't need to use pseudo-element at all. Here is the working demo.
Look closely to the above demo, the right border seems to be zigzaged a little at the end (because of the top and left borders). You can try using inset box-shadow instead for better result:
ul > li.active {
box-shadow:-5px 0 yellow inset;
}
Updated demo
NOTE: if you have some inline element (like the a element) as the most direct child (and fill the parent space), you should set style display:block for that element, otherwise it will seem to be hidden after being applied the style position:relative.
Is this what you're after?
http://jsfiddle.net/m8A3e/1/
First of all I removed the float because floats and position: absolute; can't be used together. Then I gave the li relative positioning and gave the marker the proper top/right positions.

Reserve space for pseudo element before on mouse over

I want to add image to every li, but I would like to display it only on mouse over.
However, I want to avoid 'moving' effect, which is consequence of new element (image) added to DOM. I tried to fix it with visibility:hidden, since that takes space, but without luck.
Here's the simple example, as you can see, on hovering these li's, they are moving on the right.
What is the simplest way to achieve this?
http://jsfiddle.net/UQAjh/
You'd want either position the :before pseudo element absolutely to prevent it from entering the layout flow when shown, or create the pseudo element independently from the :hover state at an opacity of 0 and set opacity to 1 when hovered.
Keeping :before out of layout flow
ul > li:hover:before {
/* all the other styles */
position: absolute;
left: 25px;
}
Fiddle: http://jsfiddle.net/marionebl/UQAjh/1/
Creating :before regardless of :hover state
ul > li:before {
/* all the other styles */
display: inline-block;
float: left;
opacity: 0;
}
ul > li:hover:before {
opacity: 1;
}
Fiddle: http://jsfiddle.net/marionebl/Nda6Z/1/

CSS on condition

Does CSS support conditions? I mean that there is hover, so when mouse is on it, element style changes.
I have class ".menu_top_line" with display:none, can I change it to "display:block", when mouse is on other element?
Like:
nav ul li:hover
{
background-color:#FFF;
// other block.display:block
}
There is no way to reference another element from inside a ruleset.
If you can write a selector that matches the element you want to manipulate which also references the element you want to hover, then you can just apply the :hover to that element in the selector.
nav ul li:hover > .menu_top_line {
display: block;
}
Otherwise you need JavaScript.
You can do it for a child element, descendent or an immediately next sibling.
You can use (>)-operator to select any immediate child element space( ) for descendent element and (+)-operator for an immediately next sibling element.
Let me show you the sibling selection similar to the answer given by #Quentin i.e. for child selection only.-
nav ul li:hover + .menu_top_line {
display: block;
}
this will address those elements with class menu_top_line that follows a li that is child of a ul that is child of a nav-element.
So there are 3 means to achieve what you want.
It is possible but only if the element you are targeting the "mouse is over some other element" condition to is some child (or grandchild) of the element you're holding the mouse over.
ul li a {
/* normal */
}
ul:hover li a {
/* a's style when the mouse is over the ul */
}

CSS ::after selector wraps and moves text in my menu

Something has changed with the latest browsers (Chrome, Safari, IE) and I can't figure out why things look broken now. The site I'm talking about is here (the "Writing" menu), and I wasn't able to build a minimized fiddle for this problem (sorry).
I have a standard CSS based menu, built from unordered nested lists which show/hide on mouse hover. For those submenus that have yet another menu, I use an automatically placed ">" character to indicate that. This is the code:
ul.menu li.arrow > a::after {
content: ">";
float: right;
padding-left: 1em;
}
So for those <li> elements that have another submenu (i.e. a nested <ul>) I want to automatically add the ">" right-aligned. This worked until recently. However, with some of the latest browser updates it seems that the ">" does not expand the width of the <ul> anymore but instead wraps around onto the next line.
I tried to somehow widen the <ul> (it's currently set to width:auto) but that didn't help; setting the <li> or the <a> inside the list item to white-space:nowrap didn't help either. However, I noticed that when I remove the float then all ">" are there, just not nicely aligned to the right side.
How can I fix this?
Try using :before instead of :after:
ul.menu li.arrow > a:before {
content: ">";
float: right;
padding-left: 1em;
}
The problem is that floating elements can only affect following elements, but not previous ones.
But if you want some separation between > and the text, use
ul.menu li.arrow:before {
content: ">";
float: right;
}
ul.menu li.arrow > a {
padding-right: 1em;
}

Stagger or Stair-Case a Menu

I have a menu, created from the usual unordered list, that I want to style horizontally with CSS so that each menu entry is slightly lower than the prior entry. The result would be a stair-case effect:
Home
News
About
Contact
My example above shows a full-line displacement for each menu entry, but what I actually want is pixel-level control of the stair-casing, so that each menu entry is potentially just a half or quarter character height displaced from the prior menu entry.
How do I make this trick work with CSS, preferably without uing CSS3? More precisely, isn't there a way to specify "this surface is to be rendered at position X,Y relative to the prior rendered item?"
The simplest way would be to manually add a margin-top to each li.
If you have a class on each li:
.first-li { margin-top: 5px; }
.second-li { margin-top: 10px; }
/* ... */
If not, then:
#menu li:nth-child(1) { margin-top: 5px; }
#menu li:nth-child(2) { margin-top: 10px; }
/* ... */
Older browsers don't support :nth-child. There is a workaround if you need to support older browsers and you don't want to add a class to each li.