Changing parent element's positioning prevents child element CSS3 transition in Firefox - html

In Webkit, the following fiddle works as expected. That is to say, #navigation's left padding is transitioned properly from 0 to 100px.
In Firefox, the identical code somehow prevents the transition from occuring.
http://jsfiddle.net/threehz/JEMN6/27/
my css:
#navigation {
background: #ccc;
-webkit-transition: padding-left 0.125s ease;
-moz-transition: padding-left 0.125s ease;
transition: padding-left 0.125s ease;
margin: 0;
padding-left: 0;
width: 100%;
}
.fixed #navigation {
padding-left: 100px;
}
.fixed #page-navigation {
position: fixed; // removing this results in #navigation transition working properly in firefox
height: auto;
border-top: 1px solid #000;
width: 100%;
}
It seems it is related to the parent element's positioning changing. As noted above, if I remove position: fixed from the parent element, the transition works in Firefox:
http://jsfiddle.net/threehz/JEMN6/28/
Problem is, for what I am trying to accomplish, the header must become fixed, AND the child padding property must transition, so simply removing the position: fixed is not an option.
Thoughts?

The transition works if you toggle it from Firebug/DevTools. In the other hand:
Using transform: translate(100px) or position: absolute + left: 100px for the li items or
Using a transition delay
don't work. The transition event is not even fired :/ ( http://jsfiddle.net/JEMN6/25/ )
It seems that FF can't handle a simultaneous redrawing of the #page-navigation container (since position: fixed takes it out the document flow) and the #navigation child, so the transition event gets aborted.
As Alex Morales suggests, you could use an animation, but you'd need the opposite one to get a transition when removing the #fixed class.
Introducing a minimal delay through JavaScript is also an option:
$('#toggle').click('on', function() {
$('body').toggleClass('fixed');
setTimeout(function () {
$('#navigation').toggleClass('get-padding')
}, 20);
});
http://jsfiddle.net/JEMN6/26/
Not an ideal solution, though.

This looks like https://bugzilla.mozilla.org/show_bug.cgi?id=625289 to me: the parent is having its CSS boxes reconstructed, which loses the old computed style on the child.

Related

Why is transition property not working in this case? [duplicate]

This question already has answers here:
Transitions on the CSS display property
(37 answers)
Closed 1 year ago.
I'm creating a hamburger menu and I'm using JavaScript to handle the ON and OFF of the menu. Here's how my code looks like:
const hamburger_menu = document.querySelector('.hamburger-menu');
const side_nav = document.querySelector('.side-nav');
hamburger_menu.addEventListener('click', () => {
side_nav.classList.toggle('open');
})
When the hamburger menu is clicked, the script will toggle the 'open' class on the hidden menu. I want the menu to have a transition effect when appearing. Here's how my SCSS looks like:
.side-nav {
background: $black;
display: none;
padding: 5rem;
position: absolute;
top: 10.4rem;
right: 0;
bottom: -1.6rem;
left: 0;
opacity: 0;
transition: all .3s ease;
z-index: 100;
&.open {
display: block;
opacity: 1;
}
}
Somehow the transition effect is not working. Is there anyone knows the reason?
Transition will never work on display property. It works on properties like width, height, opacity etc.
In your particular case, what you can do is, use height or width to control this animation.
If your sidebar will appear from the left then you will need to set the initial width to 0 and then set the width to the actual width on click. Like this:
.side_nav {
width: 0;
transition: width 1s;
&.open {
width: 200px;
}
}
Now when the open class will attach to your hamburger, it will animate the width.
replacement Display property with Visibility can help you.
visibility : hidden => visible.
Because you are switching between display: block; and display: none;.
It doesn't trigger the transition.
Instead you can hide/show by manipulating the height, opacity or width from 0 to a set value. There are most likely even more approaches other than height, opacity and width. The transition would then be triggered from value 0 to value x.

Height change transition by content display

I'm working in an Angular 9 app and I need to make an accordion menu. Everything works fine with my code except for the animation of the sub menus. I want to animate the content of a sub-menu item when display is change from'block' to 'none' and also animate it when is changing from 'block' to 'none'.
here is a couple of examples of what I need
https://codyhouse.co/demo/multi-level-accordion-menu/index.html
https://primer.fusepx.com/angular/
I also want to keep the code structure as much as possible. I just really need the content animation
Here is an stackblitz example with my code.
https://stackblitz.com/edit/angular-ivy-t6rbdp
Try this
.content {
padding: 10px;
background-color: blue;
height: 0 !important;
overflow-y: hidden;
transition: height 0.5s ease-in-out;
}
.content-open {
opacity: 1;
height: 100px !important;
}
As display which doest represent numeric values you cant do transition on that. So use properties like height.

CSS :hover works only on the lower half of the button

The page in question:
http://rainbowdoge.000webhostapp.com
The situation:
I have two buttons in the nav menu on the left side.
The upper one contains a hitbox (black for testing purposes), and an image of a rainbow. The image is changing the opacity on hover.
CSS code for that:
.icon {
opacity: 0.6;
backface-visibility: hidden;
transition: opacity 0.3s ease-in-out;
}
.iconHitbox:hover .icon {
opacity: 1;
cursor: pointer;
}
There is also an iframe on the page. The iconHitbox changes the iframe's source on click.
The problem:
If I hover over the top half of the button, the opacity doesn't change, as if a hover isn't even detected.
The solution I could think of:
I thought that maybe something else is getting in the way, but no, the setSrc() function works when I click on the upper half of the button.
This is happening because your #test1, #test2, and #test3 elements are being positioned half way over the rainbow circle. You'll need to move them out of the way.
The div with the id "test3" is overlapping with your icon. You can see it in the dev tools of your browser.
You have absolute set. If you remove absolute then adjust positioning you'll be good.
try:
#mainPageIcon {
background-color: black;
position: relative;
top: 25px;
}
.iconHitbox {
height: 8vh;
width: 8vh;
}

Inconsistent border widths on pseudo-elements because of translate3d -- but why?

(I've tried searching for this but can't seem to describe it correctly--if this answer exits, please point me in the right direction!)
I'm playing around with some css rules. I wanted to make a specific, secondary 2px-wide border on a pseudo-element appear around nav anchors in the header, which open a modal and blur an absolutely-positioned background image div #bg, which sits as such:
<body>
<div id="#bg"></div>
<header id="global-header">
<nav>...</nav>
</header>
</body>
Since I wanted to transition the blur effect, I added translate3d(0,0,0) to #bg, which smoothed the fps by galvanizing the GPU for hardware accelerated processing of CSS. It worked! ...Until I noticed that the vertical (left & right) borders for the links had inconsistent widths across the nav. They were each set at 2px, but every other one looked 1.5(??)px wide. It took me a minute to narrow down why, which ultimately was because of the translate3d transformation. I took screenshots, but I centered and moved the pseudo-elements with border-left: 2px below the header (the effect persisted), and I removed the background image itself so the effect would be easier to see. Here they are:
Inconsistent 2px calculation (with translate3d(0,0,0) on #bg)
Consistent widths (without translate3d transform on #bg)
And for reference, here's the code for the left-bordered pseudo-elements:
#global-header nav ul li a:before {
content: '';
position: absolute;
display: block;
top: 100%;
left: 50%;
height: 100%;
width: 0;
border-left: 2px solid gray;
background-color: transparent;
}
I know that translate3d creates as well as solves a possible host of issues from my searches--but why is this happening? Does it have anything to do with "subpixel calculations"? And why would these calculations render inconsistently throughout the page with hardware acceleration, on something I would assume is hard to mess up?
Edit: So, even without translate3d, the problem-lines flicker to a smaller width when the blur transitions (seen in the code from screenshots) are triggered, and I can reproduce the original issue without translate3d if I add backface-visibility: hidden to the pseudo-element itself. This could hint at general pixel rounding issues, with specific properties as triggers only being a symptom.
After further fiddling, answering my own question: This is not caused caused by hardware acceleration, which was my revised suspicion. Though the use of these effects showcased the problem in my particular case, I was able to recreate a version of my issue without them.
By removing transform3d from the #bg element:
#bg {
.
.
.
/* transform: translate3d(0,0,0); */
}
And, without the backface-visibility property as well, I added some width to the pseudo-element in order to see what these borders would normally look like:
#global-header nav ul li a:before {
content: '';
position: absolute;
display: block;
/* top: 100%; */
/* left: 50%; */
height: 72px;
width: 1px;
border: 2px solid black;
/* backface-visibility: hidden; */
/* border-left: 2px solid black; */
background-color: transparent;
/* transition: height .2s ease; */
}
Duh: I should have expected the result, since earlier I had tried to use the element itself (by making it 1-2px wide and coloring it) instead of border-left, which at the time seemed to fix the issue. Of course, when I did it this time using the above css, the base problem reappeared.
Though I still don't know why the aforementioned properties showcased the problem with border-left as well, addressing this might be too sporadic/situation-dependent to field here, and likely still has more to do with browser rendering than anything else.
Anyway, my question was why transform3d caused this effect, and the answer is, at least in this case, it didn't--it just made it more obvious.

Z-index absolute positioning confusion

In the following example I am trying to get the pop out "tickets" to show in front of the other doors:
http://codepen.io/anon/pen/EVMXVz
I have attempted to apply a higher z-index on the div.appeal-details when the article is hovered over - I'm unsure why this isn't working:
article:hover .record .jukebox-ticket {
animation: growTicket 0.4s ease-in-out;
display: block;
position: absolute;
top: 150px;
margin: 0px auto;
z-index: 20;
}
My understanding is that the higher z-index combined with absolutely positioning should work - but clearly not.
Keen to avoid JS, but will do if needed.
Thanks!
You may add
position:relative; z-index:1;
to your article and for article:hover higher
z-index:2;
or 10;
Check example: http://codepen.io/anon/pen/zvbdrB
P.S. And than there is no need in javascript part as i can understand.