Skip to main content

filter · CSS filters

Move CSS to head (move_css_to_head)

Category:
CSS
CoreFilters:
No
OptimizeForBandwidth:
No
Risk:
Generally safe

move_css_to_head collects stylesheet references that sit in the <body> and appends them to the end of <head>. Stylesheets discovered in the body still apply, but the browser finds them late in the parse, and a late stylesheet can repaint content that was already shown without it. Gathering them into <head> puts every download where the browser expects stylesheets and starts them all at once.

How it works

Not a core filter; enable it by name. Live demo: move_css_to_head.

When it helps and when it does not

It helps on pages whose markup carries <link> or <style> elements inside the body, which is typical of older templates and CMS output that renders per-section stylesheets where the section appears. On pages that already keep their CSS in <head> there is nothing to move and the filter is a no-op. The filter changes where stylesheets load from, not their order relative to each other, so the cascade survives; the visible difference is that it removes the repaint a late stylesheet would cause.

How it decides

The first </head> is the anchor, and every <style> block and stylesheet <link> after it moves to the end of <head>, in original order. A stylesheet inside <noscript>, or a <style scoped> block, stays where the author put it, and styles after it are not moved either. When move_css_above_scripts is also enabled, the first anchor in the document, the </head> or the first <script>, decides where the styles go.

When to use it

  • Not in CoreFilters: it runs only when you enable it by name.
  • Risk rating on these docs: Generally safe.

Risks

  • Stylesheets a script deliberately placed in the body, for example one that swaps a <link> after load, are moved as well; disable the filter for such pages.

  • Verify with the X-Mod-Pagespeed response header and a ?PageSpeedFilters=-move_css_to_head comparison; Is it working? has the steps.

Configuration

Enable it in the module configuration, at server, virtual-host or location scope:

Apache

ModPagespeedEnableFilters move_css_to_head

nginx

pagespeed EnableFilters move_css_to_head;

IIS (pagespeed.config)

pagespeed EnableFilters move_css_to_head
<!-- before -->
<head>
  ...no stylesheet for comments...
</head>
<body>
  <article>...</article>
  <link rel="stylesheet" href="/css/comments.css" />
</body>

<!-- after: the link is appended to the end of head -->
<head>
  ...
  <link rel="stylesheet" href="/css/comments.css" />
</head>
<body>
  <article>...</article>
</body>

On the worker

The worker runs its own pipeline, configured by flags. Its equivalent of this filter is the async css transform. Toggleable via --no-async-css; the coverage gate is tuned with --async-css-min-coverage and --async-css-min-deferred-bytes.

Scoping, ForbidFilters and the thresholds filters read: Choosing filters .

Live example

Moves stylesheets into the <head> so the browser finds them sooner.

This filter changes how the page is structured or delivered, not its size, so the example shows a source diff rather than a byte or request reduction.

See the before and after, with the source diff →

Frequently asked questions

What does the move_css_to_head filter do?
move_css_to_head collects stylesheet references that sit in the <body> and appends them to the end of <head>. Stylesheets discovered in the body still apply, but the browser finds them late in the parse, and a late stylesheet can repaint content that was already shown without it. Gathering them into <head> puts every download where the browser expects stylesheets and starts them all at once.
Is move_css_to_head enabled by default?
No. move_css_to_head is not in CoreFilters, the default RewriteLevel; it runs only when you enable it by name with EnableFilters.
How do I enable move_css_to_head on Apache and nginx?
Add ModPagespeedEnableFilters move_css_to_head on Apache or pagespeed EnableFilters move_css_to_head; on nginx. On IIS, add pagespeed EnableFilters move_css_to_head to pagespeed.config.

This page is drawn from the move_css_to_head entry on CSS filters. Every filter in one table: PageSpeed filters.

Search