CSS not selector with after content - css

Is it possible to use the :not() selector/pseudo thing with :after?
So for example if I have the following:
li:hover > ul
{
display: block;
}
li:after
{
content: " ";
width: 200px;
height: 200px;
background: #cccccc;
position: absolute;
top: -100px;
left: -100px;
}
What happens is that if a person HOVERS over the content that is created by the after it will also make the child menu display block. In other words hovering other the LI or the AFTER content is acknowledged as hovering the LI. How would I stop this, so it only does the display block when hovering the ACTUAL LI and NOT the content created using AFTER.
I thought about: li:hover:not(:after) > ul { display: none; } but hasn't worked...
Also tried: li:after:hover > ul but also didn't work.
Any ideas for this? It might seem trivial but it's causes some issues in my design so need to stop it doing it asap.

As you observe, :hover styles on an element will be triggered when hovering over its contents, including descendants and pseudo-elements. However, you can't prevent :hover styles on an element from applying to its :after pseudo-element, nor can you use :not() to select :after pseudo-elements (this is explicitly disallowed by the spec).
This is by design, so the only way around it is to not use :after, but use JavaScript to generate some other element that you can append to the li and cancel the :hover effect on.

Actualiy it is possible with the use of the attribute "pointer-events" and assign it to none in the pseudo-element :after or :before .
So it would be -> pointer-events: none; in the pseudo-element.

Related

Pseudo-class on pseudo-element

OK to be clear, I am not trying to make the (pseudo)inception for css. Just wanted to check if it's possible to add a pseudo class on a pseudo element. For eg:
.some-class:after:hover {
}
doesnt seem to work.
This works though:
.some-class:hover:after {
}
And ofcourse, this doesn't:
.some-class:hover:after:hover {
}
What I am trying to do is- there is a div. If you hover on that div, I am attaching a delete icon using :after on the div. I want to style this icon (say, have it zoom to 1.1 or so). Is this possible purely on CSS? I just need it to work on Chrome.
No, the current standard does not allow attaching pseudo-classes to pseudo-elements. The only place where a pseudo-element may appear is at the very end of a complex selector, and no other selectors or combinators may appear after it. Refer to the spec.
Some implementations like WebKit have their own rules, but they are non-standard and do not work cross-browser. They may also not apply to all pseudo-classes and/or all pseudo-elements. For example, as far as I know, :after:hover does not work on any browser, Chrome included.
Either way, you will need to use an actual element instead of a pseudo-element.
As already answered by #BoltClock that it is not possible to attach an :hover pseudo on :after so if you want, you can nest an extra element inside your container element and achieve the desired effect.
div {
height: 300px;
width: 300px;
border: 1px solid tomato;
margin: 20px;
position: relative;
}
div span {
display: none;
position: absolute;
right: 0;
top: 0;
}
div:hover span {
display: block;
transition: font-size .5s;
}
div span:hover {
font-size: 20px;
}
<div>
<span>X</span>
</div>
This will give you desired effect without using any JavaScript on your page, only down side of this is that you need to have an extra element so if you don't have any access or permission to modify your HTML then this is not for you unless you can then append an element using JavaScript.

CSS: Absolutely positioned pseudo element loses z-index?

Why would an absolutely positioned pseudo element be losing its z-index when using transition?
The fiddle:
http://jsfiddle.net/RyanWalters/jNgLL/
What's happening?
When you click on the li, it slides to the left without changing any z-index values. However, the :after content is popping up on top of the li.
What should happen?
I was hoping it would stay hidden behind the li.
The CSS (simplified a little bit, see fiddle for full example):
li {
position: relative;
transition: transform 0.2s;
}
li.active {
transform: translateX(-100px);
}
li:after {
position: absolute;
top: 0;
right: 0;
z-index: -1;
content: "Yada yada";
}
Why is the :after content not staying behind the li?
I found this on w3.org, which I think explains it: http://www.w3.org/TR/css3-transforms/#effects
Any value other than ‘none’ for the transform results in the creation of both a stacking context and a containing block. The object acts as a containing block for fixed positioned descendants.
As I understand it, your li:after pseudo-element is inside the stacking context of the li.active element, and therefore cannot appear behind it.
#BernzSed's answer is correct. Here's a solution, though:
Wrap the content inside the <li> using a <div> (or any other element) with position: relative, then the z-index: -1 on the psuedo element will force it to be behind the child element.
Here's the essential code:
HTML:
<ul>
<li><div>This is the first item</div></li>
</ul>
CSS:
li,
li div {
position: relative;
}
li:after {
position: absolute;
z-index: -1;
}
Example: http://jsfiddle.net/shshaw/jNgLL/3/
Also interesting to note: If you use a :before psuedo element, you don't need the z-index: -1 because it's already falling under the position: relative child element in the stacking order.

show div when mouse over

How can I make a link that appears when the mouse is over the main area like a youtube comment.
I have this code - but when the mouse is over the .showme class it's not visible like the showhim element.
<div class="showhim">HOVER ME<div class="showme">hai</div></div>
.showme{
display: none;
}
.showhim:hover .showme{
display : block;
}
Maybe you want the inner div to be in the flow of the outer. In that case use
.showhim:hover .showme{
display : inline-block;
}
Or, if you want to display the inner div on :hover for the inner div too, use
showme{
visibility: hidden;
}
.showhim:hover .showme{
visibility: visible;
}
Just one thing: Maybe you tested with IE 6. The dirty one from Redmond doesn't know :hover on elements other than <a/>. He doesn't know display: inline-block either by the way.

how to stop centered css dropdown menu from twitching (chrome only)

I have a css driven dropdown menu, and in Chrome when I hover over the last option the whole thing jumps to the left slightly. I assume it's because the dropdown menu is adding to the overall width of the main list even though it's styled to float. Is there any way to fix this? (it's not doing it in firefox interestingly)
I've noticed by using webdeveloper to outline elements that the last li appears to get wider when it's hovered, but none of the others do.
the applicable sourcecode is here:
http://jsfiddle.net/WsAEW/
It worked for me changing this:
#menu ul li {
display: inline;
position: relative;
}
to this:
#menu ul li {
display: inline-block;
position: relative;
}
Here is a modified jsfiddle. I think the issue is fixed. Give it a try.
http://jsfiddle.net/WsAEW/5/
BTW, I only changed the following style. The 'float left' gets the elements to line up horizontally and the 'display: block' gets the top element to size to include the drop down menu.
#menu ul li {
float: left;
display: block;
position: relative;
}

In CSS, what is a better way of forcing a line break after an element than making it a block element?

I have an H3 heading that I'd like to style as having a particular background color, but without having the element's background take up the full width of the parent element. Seeing as H3 is by default a block element, my style would need to change the element to an inline-block element, or just an inline inline element like so:
h3 {
background-color: #333;
color: white;
display: inline-block;
}
This will work fine, but only if it is immediately followed by a block element. I do not want to change the markup just to cater for this style, so I was wondering if there is a way to cause any adjacent element, irrespective of how it displays, to start on the next line?
Assume I can use CSS3.
try this:
h3:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
display:block;
width:auto;
This will make the width as small as possible (not filling the whole parent element) and make other elements appear below.
How often does it happen that the element after the <h3> is an inline element? (Usually after a header there should be like a <p>, <ul> or other block elements, although this totally depends on your html. Is it predictable? Is it an option to just turn every element that directly follows a <h3> into a block element?
h3 ~ * { display: block }
The only other way I know to have a block-element not take up all the space is floating it, but this leaves another problem.
I come across this all the time in my code, usually for div's that are inline-block'ed. The best way I've seen is to force a new line is to wrap your code in an additional div. Your original html gets the formatting you expected and the div wrapper forces a new line.
Assuming this is your h3 styling,
h3 {
display: inline-block;
}
Then just wrap it in a div.
<div>
<h3>My heading</h3>
</div>
I've had to do something similar with inline nav items that need breaking at certain points. Does this work?
h3:after {
content: "\A ";
line-height: 0;
white-space: pre;
display:inline-block;
}
I seem to remember IE7 having an issue with it.
If you don't need to center h3, this may help:
h3 {
background-color: #333;
color: white;
display: inline-block;
float: left;
clear: left;
}

Resources