CSS3 transitions disabled when using display:none as well - css

I appear to have found a flaw with CSS3 transitions. Hopefully not though. Here is the dilemma.
.element a span {
display:none;
opacity:0;
position:absolute;
top:-10px;
-webkit-transition-property:top, opacity;
-webkit-transition-duration:500ms;
}
.element a:hover span {
display:inline;
opacity:0.8;
position:absolute;
top:10px;
}
The transition does not work like this at all. If one removes the display:none attribute then it does work, however we need in this case the display:none attribute on our link so that it cannot be interfaced with before hover.
Any ideas?
Marvellous

you could try put overflow: hidden on the a, that way the span should appear invisible, without the need to use display: none; as you have moved it 10px up.
or instead of display:none; try use visibility:hidden;

Changing display:none to display:inline makes the other properties moot as far as transitions are concerned. So separate the display:none/display:block change from the class change, using setTimeout. The browser needs to see them as separate changes in order to apply your transition. Sadly I think this means you can't just use :hover but will need a JS event handler on hover.
Specifically, I would use an inline style attribute of style="display:none" that you add or remove with JS, and take display:none out of the stylesheet.
Then, in JS, after removing display:none (explicitly or via the :hover pseudoclass's style rule), use a setTimeout function that explicitly adds/removes the class. That way the "this is display:inline" change is a discrete, earlier paint-able action from the other style property changes that you want the transition rules applied to.
In the opposite direction, change the class back in an event handler, and use a setTimeout function to set display:none as an inline style. The timeout will need to match the transition duration of course (so that display:none happens after the transition is complete).

or you can try using width or height 0 combined with overflow hidden on the invisible element so it doesn't disturb any of the other elements whilst preserving the transitions.
ie.
.element a span {
overflow: hidden;
height: 0;
width: 0;
opacity:0;
position:absolute;
top:-10px;
-webkit-transition-property:top, opacity;
-webkit-transition-duration:500ms;
}
.element a:hover span {
overflow: visible;
height: ???px;
width: ???px;
opacity:0.8;
position:absolute;
top:10px;
}

I would go with JS. CSS transitions suck with heights.
Here is what I used to make a click expand function, you could change a few things and do the same on a hover
// Dropdown
$(function(){
// Target the ul sibling to keep it generic
var selector = $('.dropdown article > ul').siblings().addClass('selector');
selector.click(function(){
var targetUl = $(this).siblings('ul');
if (targetUl.hasClass('open')) {
targetUl.removeClass('open').slideUp();
} else {
targetUl.slideDown().addClass('open');
}
});
});

Related

CSS not updating in IE / Edge?

Here is the JsFiddle
I have a css rule depending on the display status of a neighbor:
#top:not([style*="display: none"]) + #bottom {
color:red;
}
When I hide the '#top' div using javascript, the color changes since the css rule is no longer valid.
This is not the case in Internet Explorer and Edge ! Am I doing something wrong or is this just a bug in Microsofts browsers ?
I would avoid that approach, as it's somewhat fragile. Instead, explicitly toggle a class on a parent element or #top, and make your CSS changes based on that:
body.toggled #bottom {
color:red;
}
body.toggled #top {
display: none;
}
$("#btn").click(function() {
$('body').toggleClass('toggled');
});
Demo

Allow pointer events to pass through a nested div

Assuming I have a container, if I have the css:
#nested2 {
pointer-events:none;
}
It does not work unless I make wrapper have the pointer-events: none. The issue is I want to have only nested2 have events pass through it and not nested1.
What is going on?
You can set pointer-events:none for the whole #wrapper, then override that style in #nested1 with pointer-events:auto:
#wrapper {
pointer-events:none;
}
#nested1 {
pointer-events:auto;
}
Of course the tradeoff here is the #wrapper won't be able to receive mouse events. However I hope you interest in the nested divs inside.

CSS - opposite of display:none

I'm trying setting up two simple css classes to toggle elements :
.hide{
display:none;
}
.show{
display:inherit;
}
It seems to work but sometimes display:inherit; return troubles so which is the exact opposite of display:none; ?
This all depends on the element you are specifying. For example <div> and <p> elements are display:block; by default, whereas <span> is display:inline; by default.
The accepted answer here provides a list of the defaults for each element based on what browser is being used.
EDIT
It appears that display: initial; will work in most browsers, although not IE. A fallback line of CSS would probably be best practice:
.show {
display: block;
display: initial;
}
If you use Javascript to do that:
document.getElementById(id).style.display = "";
And
document.getElementById(id).style.display = "none";
Can toggle the display for you.
If you are just toggling elements, you don't need two classes; you just need one class ("hide") that you add and remove for each element. When you hide the element, you add class "hide" to it, and when you show the element again, you remove class "hide".
However, if you really need two classes, I've had success with something like this:
.show{display:"";}
The blank value tells the browser to ignore that property, and it goes back to its default value.
It depends on which element you want to show, for block elements:
.show{
display: block;
}

Clicking a child doesn't trigger the parent's :active state in IE

I have found an irritating bug in IE 8-10 that prevents a parent's active state being triggered. It appears that if a child of the parent element is the target of the click event the active state on the parent element is not triggered.
Here is a working example. If you click the text inside the <li> the element wont change colour. If you click inside an <li> anywhere other than on the <p> child the element will turn blue.
This is a problem as it pretty much renders the css :active pseudo state useless in IE if the element has any children.
Has anyone encountered this problem before, and even better found a way round it?
Here's an easy workaround: add a css rule to the paragraph.
Working example
CSS
ul { list-style: none; }
li { height: 50px; margin-bottom: 4px; background: red; }
li:active { background: blue; }
p:active { background: blue; height: 100%;}
I have fixed the issue by preventing pointer-events on the child element. This way the :active state is triggered directly on the parent and doesn't need to be propagated. The only downside of this solution is you cannot attach an event listener (not even a css `:hover selector) to the child anymore. So you have to move all your event listeners to the parent.
.child { pointer-events: none; }
Here is jsFiddle https://jsbin.com/govelabuca/1/edit?css,output
Just uncomment the last line in css and compare the result in IE and other modern browser
You could add another CSS selector for the <p> tag so your
li:active { background: blue; }
will become
li:active, li p:active { background: blue; }
I would suggest you would use javascript or jquery for that when you click a child element, perform the active state of of the parent.
I've stumbled upon this on IE11. I was writing a drag-n-drop styling logic using this approach suggested by Martin.
In my case I have a row with td cell elements and using :active for the parent tr does the job for other browsers. For IE, I've added a CSS rule to target the cells (tr.myRowClass > td:active) and modified the if condition in my custom JS logic executed during the mousemove event handler of the cells:
if (style.getPropertyValue('cursor') == 'auto' || document.querySelectorAll(":active").length > 0) {
The remaining task is to find the target element:
Determine which element the mouse pointer is on top of in Javascript

Can I do this with the :hover pseudo class?

I'm familiar with the :hover psuedo class and using it for elements as well as the typical link setup we're all used to. What I am trying to do however is create a situation where hover over one element would change properties of another. For instance if I were to hover over .block1, #block2 would become visible. I would think the .css would look like something this...
.block1:hover div#block2
{
visibility:visible;
}
but that's getting me nowhere. Thoughts? I know that I could probably use javascript to make this happen (make elements appear and disappear) but I would love to find a pure css solution to this.
The element you want to change has to be a child element of the one you are hovering over.
Example CSS:
#navButton div.text {
display:none;
}
#navButton:hover div.text {
display:block;
}
This will make the text div display if you hover over the element with id="navButton".
Otherwise, use a JQuery solution:
CSS:
#navButton div.text {
display:none;
}
.hover {
display:block;
}
Javascript:
$("#navButton").hover(
function () {
$("#navButton div.text").addClass("hover");
},
function () {
$("#navButton div.text").removeClass("hover");
}
);
Edit:
You can also do this for sibling elements in CSS if the hovered element precedes the element you want to modify. Like so:
#navButton + div.text {
display:none;
}
#navButton:hover + div.text {
display:block;
}
OR
#navButton ~ div.text {
display:none;
}
#navButton:hover ~ div.text {
display:block;
}
If that second element is a descendent of the first, then it will work.
jsFiddle.

Resources