Clearing Inline CSS Properties With jQuery
The other day, I found myself with an odd CSS problem that I had not encountered before (or at least not in a really long time); my CSS class properties were being overridden by inline style attributes left over from a jQuery animation. Specifically, jQuery left a "display" property on an element's style attribute which prevented the "display" property of my CSS classes from cascading. As of late, I've been trying hard to push all my formatting into CSS classes, which is why I've probably not run into this issue before. That said, I needed to figure out how to clear the inline style value after the animation had completed. And, as it turns out, jQuery provides a really easy way to do this.
To clear the inline style values of an element, I could have simply cleared the "style" attribute:
myElement.attr( "style", "" );
But that's not really what I wanted to do; I wanted to clear a specific property - not all of the properties that may or may not exist on the element. Reseting the style attribute makes too many assumption about how the element is being used; and, in my particular case, would have further broken the code.
No - what I wanted to do is to remove the inline style for a given property. And with jQuery, this is quite simple - you set the CSS property to the empty string:
myElement.css( "target-property", "" );
This will remove the given property from the inline styles of the element; but, it will leave CSS class properties in place. Pretty awesome!
Here's the code that I demonstrated in the video. The slideToggle() method leaves a "display: block" on the DIV's inline style. This overrides the display property set by the "hidden" class.
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Clearing Inline CSS Properties With jQuery</title>
<style type="text/css">
div.box {
background-color: #F0F0F0 ;
border: 1px solid #CCCCCC ;
height: 100px ;
line-height: 100px ;
text-align: center ;
width: 150px ;
}
div.hidden {
display: none ;
}
</style>
</head>
<body>
<h1>
Clearing Inline CSS Properties With jQuery
</h1>
<p>
<a href="#" class="toggle-hidden">Toggle Hidden</a> -
<a href="#" class="toggle-slide">Toggle Slide</a> -
<a href="#" class="clear">Clear Inline CSS</a>
</p>
<div class="box">
Woohoo!
</div>
<!-- Init page scripts. -->
<script type="text/javascript" src="../jquery-1.8.3.js"></script>
<script type="text/javascript">
// Cache our target manipulation element.
var box = $( "div.box" );
$( "a.toggle-hidden" ).click(
function( event ) {
box.toggleClass( "hidden" );
}
);
$( "a.toggle-slide" ).click(
function( event ) {
box.slideToggle();
}
);
$( "a.clear" ).click(
function( event ) {
// By setting a CSS property to the empty string, jQuery
// will remove the CSS property from the inline styles of
// the target element.
//
// NOTE: This will NOT affect styles supplied by a CSS
// class in your stylesheet.
box.css( "display", "" );
}
);
</script>
</body>
</html>
I've been using jQuery for like 6 years and I only just found out that you could clear CSS this way. Better late than never!
Want to use code from this post? Check out the license.
Reader Comments
Hi,
I have comment which is not related to the jQuery feature but more to jQuery selector that you have used. var box = $( "div.box" );
How important is to tag neme before the dot.
I would appreciate if you could provide us with post or tutorial for jQuery selector optimization.
Thanks a lot.
Thanks a lot Ben for this.
I started on JQuery a year back and totally love it...
Never thought of changing inline CSS. Would sure come in handy..
@Omer
That depends on what browser you are using. In most browsers it doesn't matter, but in firefox, using just the classname appears to be a little faster.
http://jsperf.com/class-selector-with-or-without-tagname
In either case, the difference is too small to waste time on.
Some time ago I answered a question about this on stackoverflow, and came up with a whole convoluted method involving a regex. Then, one day, I accidentaly bumped into this solution while fiddling aroud in the console, and updated my answer there.
http://stackoverflow.com/questions/2465158/is-it-possible-to-remove-inline-styles-with-jquery/6553745#6553745
I don't think this has anything to do with jQuery though; assigning an empty string to the native el.style object produces the same result.
@Omer,
As Kevin was saying, there may be tiny differences in speed. I think class-based selectors seems to be the fastest thing in the recent builds of various browsers. But, I like having an element in there - helps me think about what I'm doing.
@Joseph,
Ah, very cool. The jQuery documentation seemed to indicate that they were doing something to help you; but, as long as it works, I'm with however it is actually implemented under the hood :D
@Ben ... This is some pretty cool stuff ... There are some sick-skilled javascript guys out there and I'm not quite there yet ... ;-)
Something I've been trying to figure out is how to do some url rewrite magic with hashed tabs to have them behave like regular links in the browser ...
To explain what I'm talking about there's a pretty clear example on the Atlassian site ...
http://www.atlassian.com/software/jira/overview/add-ons
If you're using chrome tools or firebug you can see this in action under the 'The JIRA Feature Tour' tabs area ... notice how the url behaves like regular links when in reality this is ajax tabs?
There magic start with var productTours() ...
Trying to figure the rest of that out ... ;-)
@Edward,
That stuff is pretty cool. I think they must be using the "push state" for URLs in modern browsers:
https://developer.mozilla.org/en-US/docs/DOM/Manipulating_the_browser_history
I've never used it myself, but it's supposed to be all the rage these days :) I guess the nice things is that you always have a full URL that the user can link to.
@Ben,
Ah TY Ben ... you're probably right ...
I can't believe it wasn't apparent as I was reading about push state just last night.
Lot's to keep up with ... now I've got something else to figure out ...
Thanks for the clue ;-)
@Ben,
Yep ... you were right ... Here's the lib they used ...
https://github.com/balupton/History.js/
Great tip! Thanks for sharing Ben!
@Edward,
The best example I've seen of the PushState stuff is on GitHub - they use it to dive down into the repo directories. AND, they use a cool side-scroll animation to make the transition. Very cool.
I've never used push state myself. AngularJS supports it (I think), but I've only used the #! notation.
@Joseph,
My pleasure!
@Ben,
Thanks for the info Ben ...
I think this may be a good use case for learning Angular and Push State at the same time by hacking a few apps together using both technologies ...
@Ben,
I almost forgot ---
I apologize for hijacking your post --- It's a habit of mine --- quite rude of me.
@Edward,
Ha ha, not a problem - all good conversation is good :)
@Omer,
I am actually using PushState on a new project. I am just building my engine right now. its using backbone.js and underscore.js and the pushstates are automatically handled by backbone.js it even has fallback to IE #. I am also pulling individual views and sections from other pages and directories. its much faster than reloading the entire site and I put in some animations to boot.
http://2013.zadesigns.com
just be warned that it just turned 2013 so this site is like 8 days into coding and depending on when and if you look at it, it will be changing daily.
@Zuriel,
Looks pretty snazzy! How are you handling the rendering on the server vs. the rendering on the client. Meaning, when you use the pushState and then someone refreshes the page, do you render the page server-side? Or do you serve the base page and then render the sub-page on the client? Such a new kind of thinking for me.
@Ben,
I render the base page (which has the header and footer in it) and just a empty container div for the content #main. backbone.js has routes and it uses those routes to serve up content. by default, if nothing is added it serves up the main page of index /pages/index.html but if there is a route then it takes that parameter and serves it up instead.
backbone.js out of the box doesn't really have this kinda stuff setup, but thats the beauty of it i guess.. is that you can do whatever you want. I have a viewManager and use that to set new views, etc.
@Zuriel,
Ah, sounds pretty cool! So basically, you're rendering the page in very similar way to the hash-bang stuff, but you're using push-state on top of it. Sounds groovy to me.
Very helpful
@Dave,
Glad you like - I've already put this to use multiple times since I learned about this feature. Super useful!
I've also stored the existing style in a variable before the animation starts, and then you can restore it using a callback function once the animation completes. That way if for some reason there are styles you want to keep, it resets back to those, minus the ones jQuery added during the animation. I had to do this when I was animating some divs that had their height equalized using JavaScript, and then were animated.
@All,
I recently found a special case in which this approach didn't work. It has to do with IE8 (and lower) and alpha-filters:
www.bennadel.com/blog/2459-Removing-Inline-Opacity-Filters-After-Fade-In-Fade-Out-Transitions-In-IE8.htm
It looks like the jQuery source code takes this into account; but, for some reason, it doesn't work with my particular situation.
Thanks a lot for for post! It helped me a lot... after being stuck since 24 hrs.. found solution from your post. Thanks again!
@Romi,
My pleasure! Glad this was able to help :)
Thanks!
it took me an hour to figure out my bug was the inline css JQ was adding, and then almost another hour to figure out how to fix it , but your solution is much easier and elegant! well done!
Nice one. I needed to remove some leftover inline styles after dynamically destroying a plugin instance. Thanks!
how can we achieve the same thing in javascript?? i mean is there any way to find only inline style properties of an element in javascript!
Tip to Cache the manipulation element helped me solve my issue..Working directly on the div class was not taking effect and once I did the cache it started working..Thanks to you and appreciate the good work.
identify insurance, authorized description etc to help you discuss with the vendor who tries to sell you the property. When you purchasing property is not an easy task in your life as it requires long cautious process to complete in an specific way. Well the same with real estate attorney's that with certain charges allows you to get home inside best deals and also vacate your own commercial or residential spot with discover to leave the land.
This will not work is what you need is to remove (or replace) a custom class.
The idea is almost the same, however:
var oldClasses = $('#elem').attr('class');
var newClasses = oldClasses.replace('bad-class', '');
$('#elem).attr('class', newClasses);