Easy Inline CSS3 Lookups in JavaScript
Tags: javascript, css, ide, tutorial
Published: 2020-02-28 05:10:08

[**NOTE:** Since writing this article, I've put this utility into an NPM package.  You can find it here: https://www.npmjs.com/package/@toolz/css3]

When using JavaScript to do inline styling, you can run into several headaches:

1. **Unless you're a Certified CSS Guru, it can occasionally be difficult to remember _all_ of the CSS3 properties that are available to you.**

1. **And even if you remember _all_ of the available properties, it can be even more daunting to remember all of the potential _static_ values that are accepted on each of those properties.**<br/>For example, if you want to set the `cursor` on a given element, there are _dozens_ of potential values.  Do you want `move` or `grab`?  And are you sure you're not forgetting a more appropriate value that's available to you?

1. **Assuming that you know exactly _which_ CSS3 property you want, and _which_ value you want to assign to that property, you're still susceptible to spelling errors that could render your desired styling moot.**<br/>For example, I've done this before: `cursor : 'grabing'`.  

1. **Many of CSS's shorthand properties accept/require free-form text (e.g., the `border` property).**<br/>But when you're writing your property, can you always, without fail, spit out the _exact_ syntax that's required for that property??  For example, when writing `margin : '10px 20px 30px 40px'`, is the _top_ margin the second value?  The third?  It may feel old-hat to you now, but sometimes I still have to carefully read my style attributes to ensure that I haven't juxtaposed my values.

1. **Inline styles can leave you devoid of IDE assistance.**<br/>If I'm writing a standalone `.css` file, my IDE does a pretty damn good job of showing me all of the available options in the autocomplete feature.  But once I start using inline styles, the IDE can range from barely-helpful to downright useless.

## This Is A Holy-War-Free Zone

Reading the "issues" I've outlined above, you may be sitting back and chortling while you think:

> That's why you don't _use_ inline styles!

So let's get one thing out of the way.  Inline-vs-class CSS is definitely one of the coding/designing/HTML/CSS/JS Holy Wars.  And I'm **not** writing this post to open that can of worms (I'll go _there_ in another, future post...)

So if you're all smug in the knowledge that you simply do **not** use inline styles - in _any_ scenario - then... this post is not for you.  Seriously.  I'd love to see you back on my blog at some future date.  Maybe we can have a coffee sometime.  But right now, for the rest of _this_ post, we're gonna be catering to the slobbering coding masses who still, for whatever reason, find it appropriate to, at least _occasionally_, use inline styles.

Have a great day!  Hope to see you around soon...

## A Useful Little Helper Object

Alright... _Are they gone???_

Good.  It was getting a little crowded in here anyway.  Now that we've all got a bit more legroom, let me show you a simple helper object I've created to assist me in my dirty, grimy, inline CSS adventures.

The complete code for my utility can be found here:

https://github.com/bytebodger/javascript-css3-lookup

Don't be afraid.  It's, literally, a _single_ JavaScript file (not counting the `README.md`).  That file's a bit long-ish (cuz it has references for basically _all_ of the CSS3 properties and their accepted values).  But there's no real _logic_ in it.

Here's an abbreviated version of what that file contains:

```javascript
const css3 = {
   background : {
      inherit : 'inherit',
      initial : 'initial',
      unset : 'unset',
      [`ex: url("bg.jpg") #fff`] : null,
      [`ex: url("bg.jpg") 20% 0% repeat-y fixed #fff`] : null,
      [`ex: url("bg.jpg") 20% 0% / contain repeat-y fixed content-box padding-box #fff`] : null,
   },
   dislay : {
      block : 'block',
      inherit : 'inherit',
      initial : 'initial',
      inline : 'inline',
      inlineBlock : 'inline-block',
      inlineTable : 'inline-table',
      listItem : 'list-item',
      none : 'none',
      table : 'table',
      tableCaption : 'table-caption',
      tableCell : 'table-cell',
      tableColumn : 'table-column',
      tableColumnGroup : 'table-column-group',
      tableFooterGroup : 'table-footer-group',
      tableHeaderGroup : 'table-header-group',
      tableRow : 'table-row',
      tableRowGroup : 'table-row-group',
      unset : 'unset',
   },
   textDecorationStyle : {
      dashed : 'dashed',
      dotted : 'dotted',
      double : 'double',
      inherit : 'inherit',
      initial : 'initial',
      solid : 'solid',
      unset : 'unset',
      wavy : 'wavy',
   },
};

export default css3;
```

There's more - a _lot_ more - in the full file.  But the snippet above will be more than suitable to illustrate how this works.  Now here's an example of how this file helps me in my daily coding:

```javascript
import React from 'react';
import css3 from './css3';

export default class MyComponent extends React.Component {
   render = () => {
      return (
         <div>
            Inline styling is Da Bomb!
         </div>
      );
   };
}
```

This is just a base React component, almost empty.  And of course, our container `<div>` currently has no styling on it whatsoever.  So let's do a little styling...

```javascript
import React from 'react';
import css3 from './css3';

export default class MyComponent extends React.Component {
   render = () => {
      return (
         <div style={{
            textDecorationStyle : css3.  // Once I type the '.', my IDE springs into action.
         }}
         >
            Inline styling is Da Bomb!
         </div>
      );
   };
}
```

As soon as I type `css3.`, my IDE recognizes that I'm calling the `css3` object and my autocomplete pops up with all the available properties on that object.  Of course, `textDecorationStyle` is one of the properties on that object.  So as soon as I type a few more letters, drilling down into `t`, then `e`, then `x` (etc.), my IDE quickly narrows down on the `textDecorationStyle` property.

That will eventually get me to here:

```javascript
import React from 'react';
import css3 from './css3';

export default class MyComponent extends React.Component {
   render = () => {
      return (
         <div style={{
            textDecorationStyle : css3.textDecorationStyle.  // My IDE springs back into action!
         }}
         >
            Inline styling is Da Bomb!
         </div>
      );
   };
}
```

Once it's clear that I've chosen the `textDecorationStyle` property, and I again type a `.`, my IDE's autocomplete pops up again.  This time, it helpfully shows me all of the potential properties that exist on `css3.textDecorationStyle`.

I find this to be tremendously useful and time-saving.  To be perfectly frank, even with 20+ of web development experience under my belt, I don't think I knew _until today_ (!) that `wavy` was even an option on the `textDecorationStyle` CSS property.  But with this little utility, I don't need to memorize all that minutiae.  It's right there in front of me, staring at me from the autocomplete, any time I type `css3.textDecorationStyle.`

In the past, when I was thinking, "Hmm... this particular bit of text really needs to be styled _differently_," I would have had to reference the third lobe of my brain (a.k.a. Google).  I woulda searched for "css text decoration style" and, in the worst-case scenario, I might have even felt compelled to browse through _several_ sites looking for just the right option.  And as powerful as Google/Stack Overflow/etc can be - they're also potential distractions.  So anything that keeps my eyes _in_ the code is a good thing.

When I'm done, the code looks like this:

```javascript
import React from 'react';
import css3 from './css3';

export default class MyComponent extends React.Component {
   render = () => {
      return (
         <div style={{
            textDecorationStyle : css3.textDecorationStyle.wavy,
         }}
         >
            Inline styling is Da Bomb!
         </div>
      );
   };
}
```

Sure, `css3.textDecorationStyle.wavy` _is_ more verbose than just using `'wavy'`.  But the lookup process was swift.  Any _other_ developer looking at this code should be able to see, through nothing more than plain reading, what's happening.  And I have the added bonus of knowing that it was impossible for me to misspell "wavy".  

(If you think it's impractical to imagine that anyone could misspell "wavy", then congratulations.  You're not _old_ like me.  You have the unbridled confidence of youth.  Enjoy it.  While it lasts...)

Also, if it's _really_ bugging you to see that "long" `css3.textDecoration.wavy` value in the `<div>`'s style, you're always welcome to _deconstruct_ it.  In theory, after thorough deconstruction, you could end up with a line that looks like this:

```javascript
textDecorationStyle : wavy,
```

If I want to force my `<div>` to display inline, that would look like this:

```javascript
import React from 'react';
import css3 from './css3';

export default class MyComponent extends React.Component {
   render = () => {
      return (
         <div style={{
            display: css3.display.inline,
            textDecorationStyle : css3.textDecorationStyle.wavy,
         }}
         >
            Inline styling is Da Bomb!
         </div>
      );
   };
}
```
Finally, let's add a background to that `<div>`.  This process will be a bit more... _manual_ than the first two properties.  Because the `background` property is a _shorthand_ property.  It allows us to chunk several different CSS values onto a single line.

Unfortunately, I know of no way to craft a helper object that will allow us to swiftly pick-and-choose the appropriate value for a _shorthand_ property from a list.  There are an infinite number of potential combinations.  But even in that scenario, the `css3` object can still provide us with _some_ assistance.

When I go back into the React class and type:

```javascript
background : css3.background.
```

The autocomplete will, once again, spring into action.  This time, it will only be able to give us _suggestions_.  There _are_ three standard properties under `background`: `inherit`, `initial`, and `unset`.  But those are basically universal "default" properties that will do nothing to help me define the `background` the way I want.  

But the `css3` object _does_ give us at least some "guidance" on typing the value.  Right in the IDE's autocomplete function, there will be three "example" properties.  Those properties aren't really meant to be chosen (which is why their values are set to `null`).  But they do demonstrate the various syntaxes that are available to properly complete that value.  

So after seeing these "helper syntaxes" in the `css3` autocomplete options, I finish the demo component as such:

```javascript
import React from 'react';
import css3 from './css3';

export default class MyComponent extends React.Component {
   render = () => {
      return (
         <div style={{
            background : 'url("someImage.png") repeat-y #ddd',
            display: css3.display.inline,
            textDecorationStyle : css3.textDecorationStyle.wavy,
         }}
         >
            Inline styling is Da Bomb!
         </div>
      );
   };
}
```

And when I'm trying to crank out some React/Angular/JavaScript/whatever code, having that built-in utility helps me to avoid _a lot_ of extraneous Googling.