# Outline CSS (outline_css)

Externalizes large inline CSS blocks. How the mod_pagespeed outline_css filter works, when to use it, its risks and the Apache, nginx and IIS directives.

Canonical URL: https://modpagespeed.com/docs/filters/outline_css/

- Category: CSS
- CoreFilters: No
- OptimizeForBandwidth: No
- Risk: Experimental

`outline_css` is the inverse of `inline_css`: it takes a large inline `<style>` block out of the HTML and serves it as a stylesheet of its own, at a rewritten `_.pagespeed.co.` URL with a long cache lifetime, leaving a `<link rel="stylesheet">` in the block's place. Not a core filter; enable it by name. Live demo: [outline_css](https://modpagespeed.com/examples/outline_css/).

## How it works

### When it helps and when it does not

The trade is about which bytes repeat. A `<style>` block rides inside the HTML, so a template that pastes the same block into every page sends it again on each of them, and when the HTML is generated per request none of those bytes can be cached. Outlining gives the block a URL of its own: the browser fetches the `.pagespeed.co.` file once, keeps it in cache, and every later page in the same directory that carries the same block reuses it; the file is named at the page's own path, so pages in other directories get their own copy. What the first view pays is a render-blocking stylesheet request the page did not have before, and a block that only one page carries, or that differs from page to page, gets a file nobody else requests. Most sites are better served by keeping CSS in real files; this filter exists for HTML whose large stylesheets are stuck inline.

### How it decides

Only a `<style>` block whose text is at least `CssOutlineMinBytes` (default 3000 bytes) is outlined. A `<style scoped>` element is left alone, because a scoped block cannot become a plain `<link>`, and so is a block whose `type` is anything other than CSS. Relative `url()` references inside the block are re-resolved against the generated file's location, so images keep loading from where they did. The generated `<link>` carries the original element's other attributes, so an `id` or `media` survives the move. The block must also arrive whole: when a flush lands in the middle of it, or a stray tag sits inside it, that block is not outlined and stays inline.

## When to use it

- Not in CoreFilters: it runs only when you enable it by name.
- Risk rating on these docs: **Experimental**.

## Risks

- A first-time visitor waits on a render-blocking stylesheet request the inline block did not have; on a page seen once, that wait costs more than the bytes it saves.

- Markup or scripts that expect the `<style>` element to exist in the page see a `<link>` instead.

- Verify with the `X-Mod-Pagespeed` response header and a `?PageSpeedFilters=-outline_css` comparison; [Is it working?](https://modpagespeed.com/docs/is-it-working/) has the steps.

## Configuration

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

**Apache**

```apache
ModPagespeedEnableFilters outline_css
```

**nginx**

```nginx
pagespeed EnableFilters outline_css;
```

**IIS (pagespeed.config)**

```text
pagespeed EnableFilters outline_css
```

```html
<!-- before: 8 KB of rules ride inside every page response -->
<style type="text/css" id="large">
  .checkout { ... }
</style>

<!-- after: the rules are fetched once and kept in the browser cache -->
<link rel="stylesheet" href="/_.pagespeed.co.HASH.css" type="text/css" id="large" />
```

```apache
# Apache
ModPagespeedEnableFilters outline_css
ModPagespeedCssOutlineMinBytes 3000
```

```nginx
# Nginx
pagespeed EnableFilters outline_css;
pagespeed CssOutlineMinBytes 3000;
```

Scoping, `ForbidFilters` and the thresholds filters read: [Choosing filters](https://modpagespeed.com/docs/filter-selection/).

## Live example

See the before and after, with the source diff: [outline_css example](https://modpagespeed.com/examples/outline_css/).

## Frequently asked questions

**What does the outline_css filter do?**

`outline_css` is the inverse of `inline_css`: it takes a large inline `<style>` block out of the HTML and serves it as a stylesheet of its own, at a rewritten `_.pagespeed.co.` URL with a long cache lifetime, leaving a `<link rel="stylesheet">` in the block's place. Not a core filter; enable it by name. Live demo: outline_css.

**Is outline_css enabled by default?**

No. `outline_css` is not in CoreFilters, the default RewriteLevel; it runs only when you enable it by name with `EnableFilters`.

**How do I enable outline_css on Apache and nginx?**

Add `ModPagespeedEnableFilters outline_css` on Apache or `pagespeed EnableFilters outline_css;` on nginx. On IIS, add `pagespeed EnableFilters outline_css` to pagespeed.config.

## Related filters

- [`combine_css`](https://modpagespeed.com/docs/filters/combine_css/): Combine CSS
- [`compute_critical_css`](https://modpagespeed.com/docs/filters/compute_critical_css/): Compute critical CSS
- [`extend_cache_css`](https://modpagespeed.com/docs/filters/extend_cache_css/): Extend cache for CSS
- [`fallback_rewrite_css_urls`](https://modpagespeed.com/docs/filters/fallback_rewrite_css_urls/): Fallback CSS URL rewriting
- [`flatten_css_imports`](https://modpagespeed.com/docs/filters/flatten_css_imports/): Flatten CSS @imports
- [`inline_css`](https://modpagespeed.com/docs/filters/inline_css/): Inline CSS
- [`inline_google_font_css`](https://modpagespeed.com/docs/filters/inline_google_font_css/): Inline Google Fonts CSS
- [`inline_import_to_link`](https://modpagespeed.com/docs/filters/inline_import_to_link/): Convert @import to link

This page is drawn from the [outline_css entry on CSS filters](https://modpagespeed.com/docs/css-filters/#outline_css). Every filter in one table: [PageSpeed filters](https://modpagespeed.com/docs/filters/).
