152

I am using this script to make a style object of all the inherited, etc. styles.

var style = css($(this));
alert (style.width);
alert (style.text-align);

With the following, the first alert will work fine, but the second one doesn't... it's interpreting the - as a minus I assume. The debugger says 'uncaught reference error'. I can't put quotes around it, though, because it isn't a string. So how do I use this object property?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Damon
  • 10,493
  • 16
  • 86
  • 144
  • Damon, addressing the ambiguity & confusion (reflected also by the divergent answers and the added/removed downvotes depending on interpretation...): did you specifically mean CSS properties, as hinted by your example & assumed by most answers, *or any JS properties*, in general, as indicated by the title and the lack of a `CSS` tag? [Yes, I know it's been 7 years. :) ] – Sz. Oct 22 '18 at 20:42
  • @Sz. I meant `any js property` because i was having a problem with referencing a property that had a hyphen in it (which also happened to be a css property... i didn't realize that there was another problem with what i was trying to do). So it's a weird one that ends up covering 2 different issues. but i'd say the top answer explains both issues. – Damon Oct 25 '18 at 18:41
  • 2
    I don't see anything at all in this question that is specific to jQuery. To me this is a ***pure*** JavaScript question. @jAndy, please excuse me for mentioning you here, but if you have the time and inclination, would you mind helping to settle the dispute whether this question is *about JavaScript* or *about jQuery*? (The question certainly *contains jQuery*. That we can all agree on, I think.) – Henke Jan 29 '21 at 11:39
  • 2
    This post is [being discussed](https://meta.stackoverflow.com/q/404829/1364007) on Meta. – Wai Ha Lee Jan 29 '21 at 12:28
  • See also: [Unable to access object property with “-” dash](https://stackoverflow.com/q/13869627/1048572) – Bergi Jan 30 '21 at 03:30

11 Answers11

194

Look at the comments. You will see that for CSS properties, the key notation is not compatible with a number of properties. Using the camel case key notation therefore is the current way:

obj.style-attr // would become

obj["styleAttr"]

Use key notation rather than dot

style["text-align"]

All arrays in JavaScript are objects and all objects are just associative arrays. This means you can refer to a place in an object just as you would refer to a key in an array.

arr[0]

or the object

obj["method"] == obj.method

A couple things to remember when accessing properties this way:

  1. they are evaluated so use strings unless you are doing something with a counter or using dynamic method names.

    This means obj[method] would give you an undefined error while obj["method"] would not

  2. You must use this notation if you are using characters that are not allowed in JavaScript variables.

This regex pretty much sums it up:

[a-zA-Z_$][0-9a-zA-Z_$]*
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
austinbv
  • 9,297
  • 6
  • 50
  • 82
  • 1
    key notation doesn't apply here - css defines styles using camel case in the keys: http://jsfiddle.net/49vkD/ – Brian Aug 19 '11 at 14:27
  • what browser? Fails for me on the hyphen gets in IE7, IE8, FFX 3.5. And, by fails I mean displays "undefined" for both of those... – Brian Aug 19 '11 at 14:34
  • @brian tested in safari and chrome displays red, red, center, center. I will try in ff now – austinbv Aug 19 '11 at 14:36
  • @brian interesting, didn't work in firefox6, I didn't know that... learn something new every day – austinbv Aug 19 '11 at 14:42
  • Yeah - I tend to err on the side of caution when it comes to making Chrome the authority ... Some very odd behaviors in chrome... for instance, chrome allows `this = ;`" http://stackoverflow.com/questions/6794369/how-to-delete-an-object-in-javascript-crossbrowser/6794533#6794533 – Brian Aug 19 '11 at 14:46
  • 1
    Removed my downvote as another responder pointed out CSS collection happened to be the subject of hte question, but the actual question was how to get a hyphenated property. – Brian Aug 19 '11 at 14:51
34

The answer to the original question is: place the property name in quotes and use array style indexing:

obj['property-with-hyphens'];

Several have pointed out that the property you are interested in is a CSS property. CSS properties that have hyphens are automatically converted to camel casing. In that case you must use the camel cased name like:

style.textAlign;

However this solution only works for CSS properties. For example,

obj['a-b'] = 2;
alert(obj.aB);          // undefined
alert(obj['a-b']);      // 2
Henke
  • 4,445
  • 3
  • 31
  • 44
Stoney
  • 698
  • 5
  • 11
  • 2
    @Brian You are correct for CSS properties. However, I was answering the original general question "How do I reference a javascript object property with a hyphen in it?" Here is an updated version of your jsfiddle: http://jsfiddle.net/49vkD/1/ – Stoney Aug 19 '11 at 14:48
  • 1
    indeed I narrowed the scope of the answers here on my own - I assumed the OP meant specifically style objects. Removed my down-vote as the question was a bit more open ended than that. – Brian Aug 19 '11 at 14:50
  • I think you are correct. That is what probably what Damon wanted. I read it too literally. – Stoney Aug 19 '11 at 15:05
  • You ***must*** use the camel cased name. Not *can*. – Oriol Jul 30 '16 at 01:58
22

CSS properties with a - are represented in camelCase in JavaScript objects. That would be:

alert( style.textAlign );

You could also use a bracket notation to use the string:

alert( style['text-align'] );

Property names may only contain characters, numbers, the well known $ sign and the _ (thanks to pimvdb).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
jAndy
  • 231,737
  • 57
  • 305
  • 359
  • the latter works.. one of those syntaxy things I just missed out on. the script I referenced uses the regular css style names, but still useful to know about! – Damon Aug 19 '11 at 14:12
  • property names cannot start with numbers though – austinbv Aug 19 '11 at 14:39
  • Property names can contain a vast ammount of Unicode characters. It's ok with the spec and it's ok with the browsers. For example: `var ò_ó = 'angry';` – Camilo Martin Sep 21 '12 at 11:24
  • **Do not use the second code.** CSS properties are camel-cased. Your code might work on some browsers but is not standard. – Oriol Jul 30 '16 at 01:58
17

Use brackets:

var notTheFlippingStyleObject = {
    'a-b': 1
};

console.log(notTheFlippingStyleObject["a-b"] === 1); // true

More information on objects: MDN

NOTE: If you are accessing the style object, CSSStyleDeclaration, you must use camelCase to access it from JavaScript. More information is here.

Joe
  • 80,724
  • 18
  • 127
  • 145
  • 1
    You're not appeasing me - you're appeasing w3c standard, per numerous other responders to this question: http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSS2Properties, but upvoted just the same ... – Brian Aug 19 '11 at 14:41
  • 2
    **Do not use this code.** It's not that camel cased CSS properties are more cross-browser, it's that using hyphens instead of camel case is not standard and should not work. – Oriol Jul 30 '16 at 02:03
5

To directly answer the question: style['text-align'] is how you would reference a property with a hyphen in it. But style.textAlign (or style['textAlign']) is what should be used in this case.

Dawson Toth
  • 5,580
  • 2
  • 22
  • 37
5
alert(style.textAlign)

or

alert(style["textAlign"]);
Brian
  • 2,772
  • 15
  • 12
4

Hyphenated style properties are referenced via camelCase in JavaScript, so use style.textAlign.

Jonny Buchanan
  • 61,926
  • 17
  • 143
  • 150
4

To solve your problem: The CSS properties with hyphens in them are represented by JavaScript properties in camelCase to avoid this problem. You want: style.textAlign.

To answer the question: Use square bracket notation: obj.prop is the same as obj["prop"] so you can access property names using strings and use characters that are forbidden in identifiers.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
3

I think in the case of CSS styles they get changed to camelCase in JavaScript, so test-align becomes textAlign.

In the general case, where you want to access a property that contains non-standard characters, you use array-style: ['text-align']

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
GordonM
  • 31,179
  • 15
  • 87
  • 129
2

The object property names are not one-to-one matches for the CSS names.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Doug Chamberlain
  • 11,192
  • 9
  • 51
  • 91
0

At first, I wondered why the solution didn't work on my end:

api['data-sitekey'] // Returns undefined

...later on I figured out that accessing data attributes was different:

It should be like this:

var api = document.getElementById("some-api");
api.dataset.sitekey
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Woppi
  • 5,303
  • 11
  • 57
  • 81