0

If you're styling an <input> element with Javascript, it appears that any properties you set this way get ignored in a :focus rule.

I've an example which illustrates this:

  • Initially the background and border of the input element is set the same as the surrounding element (div.header)
  • Clicking on the [open] link opens up the div.body element, which was initially not shown.
  • I want to make it clear that the title is a text field, so change the background and border of the input to match the textarea that was just revealed.

I have a :focus rule for both the textarea and the input, to color the background yellow so it's obvious that the text field has focus.

But this doesn't work on the input element, seemingly because I've programmatically set those properties. If I don't set them, then the :focus works as expected. If the :focus rule sets properties that aren't also set in .css(), then they're honored.

This is true on Safari, Firefox, Chrome and IE, so clearly is "expected behaviour", but I can't find anything online that says (why) this is correct.

Obviously I can implement what I want using blur and focus handlers, but I'm trying to understand why this is the way it is.

Elbin
  • 492
  • 1
  • 3
  • 11
  • setting css using .css sets it directly to the style attribute which overrides everything in the stylesheet that is not `!important`. Instead, you should be using classes. – Kevin B Jun 20 '13 at 21:26

2 Answers2

3

If you set the style of an element directly, then that is the same as using the HTML style attribute. It comes after any selector in the cascade.

Generally, to deal with CSS changes nicely with JavaScript you prepare your stylesheets in advance (as proper stylesheets) and then change the element so it matches new selectors (often by modifying its class list).

Alternatively, you can modify the stylesheet itself with JavaScript.

Community
  • 1
  • 1
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • Ah, thanks for the comment on the style attribute. My first thought was "but I'm not setting :focus, so why is that true", but experimentation reveals that if you set properties inline, then they even override :focus. My mental model is clearly not quite right. – Elbin Jun 20 '13 at 21:34
2

This has to do with specificity, and it is documented by the W3C, specifically

Specificity has four components; let’s call them a, b, c and d. Component “a” is the most distinguishing, “d” the least.

  • Component “a” is quite simple: it’s 1 for a declaration in a style attribute, otherwise it’s 0.

Since .css updates the style attribute directly, it has higher specificity than anything in your stylesheet. You could either use !important go give greater importance (which has higher precedence than specificity), but a better alternative would be to use classes (.addClass) instead of altering the style attribute directly.

Community
  • 1
  • 1
Explosion Pills
  • 188,624
  • 52
  • 326
  • 405
  • Thanks, going with classes is a nice way to do this. Here's a [hacked modification](http://jsfiddle.net/neilbowers/Gat7B/2/) of my original example (above) – Elbin Jun 21 '13 at 11:40