Show() and hide() were simplified (well, their internal implementation) and existing code that you wrote that uses them might not work anymore.
Why break something so simple?!
It wasn’t until I read their post that I understood that their job wasn’t so easy. There’s a few edge cases that don’t have simple answers.
Problem #1: They’re not responsive
When you call show() on an element, the CSS display value is inserted right into the element’s style attribute. The problem occurs if an element can have a different display value dependent on another factor, such as adding a class or a media query going into effect.
In the above screen recording, the developer intended to have div.child to have a value of display: block . However, jQuery thwarted this when the call to show() set display: inline in the element’s style attribute, tying the developer’s hands.
Sources:
- https://github.com/jquery/jquery/issues/1767
- https://jsfiddle.net/jinglesthula/ZttLJ/
Problem #2: They hurt performance
How could this hurt performance? Basically, jQuery has to keep track of the current CSS tree, which is costly. Paul Irish found this was the biggest bottleneck when loading Wikipedia’s visual editor. He brought up an important point:
Aside: Now that I’m looking, this magic behavior doesn’t make much sense. There seem to be two edge cases that have caused jQuery to punish every app’s performance:
- div { display:none; } is defined and user wants to override that with show()
- User has a custom display value defined on the inline style.
Is baking in support for these two edge cases into one of jQuery’s most simple looking APIs worth being the largest bottleneck in this editor?
Source: https://github.com/jquery/jquery.com/issues/88
What situation does jQuery 3.0 break hide() and show()?
If you have elements in a stylesheet that are set to display: none , the .show()method will no longer override that. So the most important rule for moving to jQuery 3.0 is this: Don’t use a stylesheet to set the default of display: noneand then try to use .show()– or any method that shows elements, such as .slideDown()and .fadeIn()– to make it visible.
Check out the following JSFIddle: https://jsfiddle.net/xwvzkx9y/2/
Because the JSFiddle referencing jQuery edge (3.0), slideToggle no-longer functions because the element has the “hide” class, which jQuery will no-longer override. Removing “hide” fixes this, but the element is no-longer hidden by default. Replacing the ‘hide’ class with display: none on the element is another approved solution.
Okay. What do I do instead?
Well, they’re going to keep show() and hide() around but they removed the expensive calls they were doing that supported the few edge cases. From the blog post:
If you need an element to be hidden by default, the best way is to add a class name like “hidden” to the element and define that class to be display: none in a stylesheet. Then you can add or remove that class using jQuery’s .addClass() and .removeClass() methods to control visibility. Alternately, you can have a .ready() handler call .hide() on the elements before they are displayed on the page. Or, if you really must retain the stylesheet default, you can use .css(“display”, “block”) (or the appropriate display value) to override the stylesheet.
Personally I think suggesting calling hide() in the ready() handler is a poor suggestion. That’s going to run the risk of flash of unstyled content, which I don’t believe I’m alone in thinking FOUC appears unprofessional.
Use [add|remove]Class()
Using this method, it doesn’t matter if the div has a different display value for different media queries, providing you the ability to toggle an element’s display while also giving you the power to handle special situations (e.g. media queries). JSFiddle available at https://jsfiddle.net/m0ofoo4y/.