Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does styling TDs in jquery make the markup insane?

I'm trying to add a simple border to all the table cells in a table.

It's important that my markup remains simple for some other functionality I have in place to work.

Let's say I style tds like this:

$('td').css('border', '1px solid #000');

this ends up as my result:

<td style=​"border-top-width:​ 1px;​ border-right-width:​ 1px;​ border-bottom-width:​ 1px;​ border-left-width:​ 1px;​ border-top-style:​ solid;​ border-right-style:​ solid;​ border-bottom-style:​ solid;​ border-left-style:​ solid;​ border-top-color:​ rgb(0, 0, 0)​;​ border-right-color:​ rgb(0, 0, 0)​;​ border-bottom-color:​ rgb(0, 0, 0)​;​ border-left-color:​ rgb(0, 0, 0)​;​ ">​…​/td>

Classes also wouldn't be appropriate for what I'm trying to do. Why are my cells being formatted in this ridiculous way?

like image 362
ionfish Avatar asked Jun 30 '11 16:06

ionfish


1 Answers

This is how browsers handle shorthand CSS properties; some browsers may implement the human-readable representation differently from the internal representation, but in reality,

border: 1px solid #000

is shorthand for

border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
border-top-style: solid;
border-right-style: solid;
border-bottom-style: solid;
border-left-style: solid;
border-top-color: #000;
border-right-color: #000;
border-bottom-color: #000;
border-left-color: #000;

with a number of possible representations of #000.

I tested in both Chrome and Safari (both WebKit browsers), and setting that property directly in the DOM (element.style.border = '1px solid #000') had exactly that result. This is the behavior of WebKit, not jQuery.

Furthermore, this is a great example to underscore the fact that the DOM is different from markup, and ought to be treated differently. Even in a designMode/contentEditable scenario (which is the only really reasonable use of direct styling instead of CSS classes), just snatching the innerHTML representation of an element is a whole host of potential risks. You'll see other manifestations of this in older versions of IE, whose "markup" representations of the DOM are completely insane. It's not uncommon to see stuff like:

<div class="foo">...</div>

become:

<DIV CLASS="foo" _JQUERY12903579="qwertyuiop" HASLAYOUT=TRUE etc etc etc>...</DIV>

And just as DOM and markup are not the same thing, it's important to realize that an attribute and a property are not the same thing. Ultimately, the jQuery.css method is implemented by assigning values to properties of element.style (eg collection.css({ border: '1px solid #000' }) is roughly equivalent to collection.each(function() { this.style.border = '1px solid #000' }); while collection.attr('style', 'border: 1px solid #000') is equivalent to collection.each(function() { this.setAttribute('style', 'border: 1px solid #000'); }). By setting the attribute rather than properties, what you're doing is effectively like retroactively editing the HTML markup. This can lead to unpredictable results if you also have properties set that conflict.

Also note that by using attr('style', ...), you are probably overriding all of the elements' inline styles.

like image 52
eyelidlessness Avatar answered Sep 29 '22 10:09

eyelidlessness