# CSS: “letter-spacing”: “NaNrem” is not a “letter-spacing” value.

> Canonical HTML version: https://rocketvalidator.com/html-validation/css-letter-spacing-nanrem-is-not-a-letter-spacing-value
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

`NaN` in JavaScript stands for "Not a Number" and appears when a numeric operation fails — for example, parsing a non-numeric string with `parseFloat()`, dividing `0` by `0`, or referencing an `undefined` variable in arithmetic. When this `NaN` value gets concatenated with a unit string like `"rem"`, the result is `"NaNrem"`, which is meaningless to CSS. The browser cannot interpret it, and the W3C validator flags it as an invalid `letter-spacing` value.

This issue almost always originates from dynamically generated styles — either through JavaScript that sets inline styles, a server-side template that computes CSS values, or a CSS-in-JS library. The rendered HTML ends up containing something like `style="letter-spacing: NaNrem"`, which the validator rightly rejects.

Beyond validation, this is a practical problem: the browser will ignore the invalid declaration entirely, so whatever letter-spacing you intended won't be applied. Your layout may look different than expected, and the invalid value in the markup signals a bug in your code that could affect other computed styles too.

## How to Fix It

1. **Trace the source of the value.** Search your codebase for where `letter-spacing` is set. If it's an inline style, look at the JavaScript or server-side code that generates it.

2. **Validate the number before using it.** In JavaScript, use `Number.isNaN()` or `isFinite()` to check that a computed value is valid before applying it.

3. **Provide a sensible fallback.** If the calculation might fail, default to a known-good value like `0` or `normal`.

4. **Fix the root cause.** Determine *why* the calculation produces `NaN` — common causes include missing data attributes, `undefined` variables, or parsing non-numeric strings.

## Examples

### ❌ Invalid: `NaN` concatenated with a unit

This is what the rendered HTML looks like when the bug occurs:

```html
<p style="letter-spacing: NaNrem">Spaced text</p>
```

The JavaScript that likely produced it:

```javascript
// Bug: getAttribute returns null if data-spacing is missing
let spacing = parseFloat(element.getAttribute('data-spacing'));
element.style.letterSpacing = spacing + 'rem'; // "NaNrem" if attribute is missing
```

### ✅ Fixed: Validate the value before applying it

```javascript
let raw = parseFloat(element.getAttribute('data-spacing'));
let spacing = Number.isFinite(raw) ? raw : 0.1; // fallback to 0.1
element.style.letterSpacing = spacing + 'rem';
```

This produces valid inline CSS:

```html
<p style="letter-spacing: 0.1rem">Spaced text</p>
```

### ✅ Fixed: Using a static CSS value

If the letter-spacing doesn't need to be dynamic, the simplest fix is to use a plain CSS rule instead of computing it in JavaScript:

```html
<style>
  .spaced-text {
    letter-spacing: 0.1rem;
  }
</style>
<p class="spaced-text">Spaced text</p>
```

### ✅ Fixed: Server-side template with a guard

If a server-side template generates the style, add a check before rendering:

```html
<!-- Pseudocode for a template engine -->
<!-- Only output the style attribute if the value is a valid number -->
<p style="letter-spacing: 0.05rem">Spaced text</p>
```

Ensure your template logic verifies the value is numeric before injecting it into the markup. If the value is missing or invalid, either omit the `style` attribute entirely or use a safe default.

### Valid `letter-spacing` values for reference

The `letter-spacing` property accepts:

- The keyword `normal` (default, lets the browser decide)
- Any valid CSS length: `0.1rem`, `1px`, `0.05em`, `2px`, etc.
- `0` (no extra spacing)

The numeric part must always be a real number — `NaN`, `Infinity`, and empty strings are never valid.
