## Where to put custom CSS and JavaScript

URL: https://hub.jkdevstudio.com/knowledge-base/customization/where-to-put-custom-css-and-javascript
Updated: 2026-09-06
Summary: The four places custom code can live in WordPress, which one survives a theme update, and why the theme files themselves are the wrong answer every time.

You want to change something the settings do not cover, and you have a few lines of CSS or a script to add. Where those lines go decides whether they survive your next theme update.

## The short answer

A few lines of CSS go in [[Appearance > Customize > Additional CSS]]. Anything larger, and anything involving JavaScript, goes in a child theme.

Never edit the theme files. An update replaces them, and your changes go with it, silently and completely.

## The four places, and what each one survives

<table> <thead> <tr> <th>Where</th> <th>Good for</th> <th>Survives a theme update</th> <th>Survives a theme change</th> </tr> </thead> <tbody> <tr> <td>Additional CSS in the Customizer</td> <td>A handful of CSS rules</td> <td>Yes</td> <td>No</td> </tr> <tr> <td>A child theme</td> <td>CSS, JavaScript, template overrides, PHP</td> <td>Yes</td> <td>No</td> </tr> <tr> <td>A site specific plugin</td> <td>PHP that is about your site, not its design</td> <td>Yes</td> <td>Yes</td> </tr> <tr> <td>The theme files</td> <td>Nothing</td> <td>No</td> <td>No</td> </tr> </tbody> </table>

The last row is the one that matters. Editing `style.css` or a template inside the parent theme works until the day you update, and then it is gone with no warning and no copy.

## Additional CSS

WordPress ships a CSS box in the Customizer. Open [[Appearance > Customize > Additional CSS]] and type into it. The preview updates as you type, so you can see the rule land before you save.

What it is right for: overriding a color, adjusting spacing on one element, hiding something the settings do not have a switch for.

Its limits are worth knowing up front. It holds CSS only, it is stored per theme so switching theme leaves it behind, and it has no syntax checking, so one missing brace can break every rule after it. If your CSS box is over a hundred lines or so, it has outgrown the box.

<div data-callout="tip">

**Find the class with the browser inspector before writing anything.**

Right click the element, choose **Inspect**, and read the class names on it. Guessing at selectors is where most of the time goes.

</div>

## A child theme

A child theme is a small theme of your own that inherits everything from the real one. Your files sit in a separate folder, so the parent can update as often as it likes and nothing of yours is touched.

This is the right home for a stylesheet longer than the Customizer box comfortably holds, for any JavaScript, and for changing a template rather than restyling it.

<a data-type="kb-embed" href="/knowledge-base/hooks-filters/child-themes-and-overrides">Child themes, template overrides and hooks</a>

<a data-type="kb-embed" href="/knowledge-base/customization/white-label-and-child-theme">White label and the child theme generator</a>

## JavaScript, and why it does not go in the CSS box

The Customizer CSS box stores CSS. It will not run a script, and pasting one there does nothing.

Two correct routes:

Enqueue it from a child theme. Put the file in the child theme folder and register it in the child theme's `functions.php`, so WordPress loads it in the right order alongside everything else.

```php
add_action( 'wp_enqueue_scripts', function () {
	wp_enqueue_script(
		'my-custom-script',
		get_stylesheet_directory_uri() . '/js/custom.js',
		array(),
		'1.0.0',
		true
	);
} );
```

Or, for a third party snippet such as an analytics or chat widget, use a plugin whose job is inserting code into the page head or footer. That is the better route for anything you did not write, because it keeps the snippet with the site rather than with the theme.

## Why not the theme editor in the admin

<div data-callout="danger">

**The file editor at [[Appearance > Theme File Editor]] edits live files with no undo and no copy.**

A syntax error there takes the whole site down, including the admin screen you would use to fix it. Many hosts disable it for exactly that reason, and if yours has not, treat it as read only.

</div>

## Common questions

<details><summary>My CSS is being ignored</summary>

Usually a specificity problem, meaning some other rule is more specific and wins, so inspect the element, find the rule that is winning and write a selector at least as specific, reaching for `!important` last because it makes the next override harder for the same reason.

</details>

<details><summary>I changed the CSS and the site looks the same</summary>

Clear your caching plugin and any cache at your host or CDN, then load the page in a private window, which rules out your own browser in one step.

</details>

<details><summary>Will Additional CSS come with me to a new theme?</summary>

No, it is stored per theme so a new theme starts with an empty box, which is why it is worth copying the contents out before switching.

</details>

<details><summary>Can I put custom code in a plugin instead?</summary>

Yes, and for PHP that is not about appearance it is the better choice, because a site specific plugin survives changing theme while a child theme does not, though design code still belongs with the design.

</details>

<details><summary>It still is not working</summary>

Note whether the rule appears at all in the inspector, because a rule that shows but is crossed out is being overridden and that is a selector problem, while a rule that does not appear at all never loaded and that is a caching problem or a syntax error earlier in the file. Those are two different searches, and telling them apart first saves the most time.

</details>

## Still stuck

[Open a support ticket](https://hub.jkdevstudio.com/support) with the rule you are trying to apply and a link to the page.