Reserve space for pseudo element before on mouse over - html

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/

Related

element + element cant access :before pseudo

I have a situation where i have two elements which are same level in DOM (neighbours). When i hover element which is before in DOM i want the element below it to be shown. Also i want access child of the element Im showing and show its :before pseudo element.
SCSS
&__wrapper {
display: table;
table-layout: fixed;
&:hover {
+ .filter-time__shortcuts {
opacity: 1;
visibility: visible;
pointer-events: auto;
transform: scale(1) translateY(0);
.filter-time__shortcuts-list {
transform: scale(0.5);
&:before {
display: block;
}
}
}
}
Everything works except displaying of :before pseudo element. For some reason it cant access it but it can access .filter-time__shortcuts-list.
When i move the :hover to parent of both elements, where both are children and there is no need for + selector it works. Whats going on?
Compiled CSS
.filter-time__wrapper:hover + .filter-time__shortcuts .filter-time__shortcuts-list:before {
display: block; }
edit: https://codepen.io/riogrande/pen/vWExqN
Ok so the answer is that css really was accessing the :before element. The thing was when i wanted to access the dropdown with mouse I'm not really hovering the trigger anymore. When i put the hover on the parent I'm hovering the trigger (the whole parent) all the time.

Can somebody please explain to me this css code

Hi I am new to css and I have came across this text underline animation, I couldn't understand how it works. If I just take something out of this code it just stops working. Thanks in advance!
body {
background-color: black;
}
body a {
font-weight: 200;
font-size: 18px;
text-transform: uppercase;
text-decoration: none;
position: relative;
color: #fff;
}
body a:visited {
color: white;
}
body a:hover {
color: white;
}
body a:after {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 0%;
border-bottom: 2px solid #fff;
transition: 0.4s;
}
body a:hover:after {
width: 100%;
}
<body>
aaaaaaaaaaaaaaaaaaaaaaaaaaaaa
</body>
An :after psuedo CSS means that another "virtual" element is appended after the selected element
the psuedo element appended on a:after is a simple element with bottom border but is without width (0%)
the transition property on that element means, that all properties of that element when changed will be animated
so...
when you hover the element (stated in body a:hover:after) - the width of that "virtual" element is set to 100% - and the animation takes place
What's really important here are the pseudo-elements ":after" and ":before" (although this last one not present here).
This part here is what makes it come to life:
body a:after {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 0%;
border-bottom: 2px solid #fff;
transition: 0.4s;
}
You see, basically you're looking at the declaration of properties of an element's pseudo element. (You might want to dig in a bit into CSS-CSS3).
It states that after triggering the hover event on an anchor that is a child of body it will make its pseudo element have a bottom border of 2 pixels of width, with a white solid color and a transition of 0.4 seconds.
We can tell by the other declarations that the width of the pseudo-element is 0% in its initial state and after hovering it goes to 100% with a transition (making it go from left to right as seen in the example).
There's much things to consider in this CSS code but you should really learn the basics!
This line creates the animation:
transition: 0.4s;
You will notice that the body a:hover:after rule has a width of 100%. Well, that transition property tells the render engine that there is an animation to be performed on any property that has a value change between the normal and hover state.
When you hover, the render engine reads that you want to set the width property to 100%. Before hover it was set at 0%. Transition says, "ok, on hover, animate the width property from 0 to 100% over a period of 4 tenths of a second.
This will be true of any properties that differ between the hover and non-hover state. In other words, you could animate more than one property at a time so long as the two states define the same property with different values.

CSS: Background of top element hiding child element overflow

I currently need to do this in CSS:
This is a vertical menu so the yellow "div" count is not fixed, could be 5 like it could be 7.
For now, I have a div with this CSS applied:
#main-menu {
width: 250px;
height: 100%;
padding-top: 50px;
}
That contains the yellow div (nothing special). Then I added a "before" pseudo-element like this:
#main-menu::before {
height:624px;
width:250px;
background-image: url("../img/SSC_fondgris_96_Background.png");
content: " ";
position:absolute;
top:0;
}
The image used is just the curve with a transparent background on the left and the grey on the right. This results in the the image above. The issue is that I'd like to have an hover effect on the yellow div's but I can't get that because the "before" element is on top of them (which is wanted in order to allow the curve to hide the overflow of yellow items) and therefore, the "hover" effect is not applied for the yellow divs.
I guess that it's because the hover is done on the "before" pseudo element and that's exacly my issue. So the question is: is it possible to have an image hidding the overflow of child elements but allowing these children to have a hover effect? Bascailly, a z-index for hover effect:-D
The goal here would also be to avoid using JavaScript to do such things...
Use pointer-events:none on the pseudo-element
From MDN
The CSS property pointer-events allows authors to control under what circumstances (if any) a particular graphic element can become the target of mouse events. When this property is unspecified, the same characteristics of the visiblePainted value apply to SVG content.
ul {
list-style: none;
width: 50%;
position: relative;
}
ul::before {
content: '';
position: absolute;
width: 25%;
height: 100%;
top: 0;
right: 0;
background: rgba(255, 0, 0, 0.5);
pointer-events: none;
}
li {
padding: 25px 0;
background: #000;
margin-bottom: 1em;
}
li:hover {
background: orange;
}
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
You should be able to "click through" the pseudo element by negating the pointer events on the element:
#main-menu::before {
height:624px;
width:250px;
background-image: url("../img/SSC_fondgris_96_Background.png");
content: " ";
position:absolute;
top:0;
/* Add the below */
pointer-events: none;
}
... let me know how that works for you.
I need to add that browser support is a little dodge though - only IE11 ... caniuse - pointer-events
You can achieve the effect you want by introducing a third, transparent element which you position over the top of the transparent/grey image.
If your third, transparent element is exactly congruent with the yellow div (two layers below), then you can apply :hover effects to the uppermost, transparent element and it will look like the bottom-most element is responding to the hover.

CSS - hover one item and remove content of another item

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.

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.