40

I know script files can use the DEFER and ASYNC keywords on a resource include. Do these keywords also work for stylesheet (i.e., CSS) includes?

Syntax would presumably be:

<link rel="stylesheet" type="text/css" href="./path/to/style.css" defer />

I just don't know if it's allowed or not.

Doug
  • 4,486
  • 9
  • 29
  • 39

5 Answers5

34

Defer and Async are specific attributes of the tag <script> https://developer.mozilla.org/en/docs/Web/HTML/Element/script

They will not work in other tags, because they don't exist there. A stylesheet is not a script that contains logic to be executed in parallel or after the loading. A stylesheet is a list of static styles that get applied atomically to html.

fmsf
  • 33,514
  • 48
  • 140
  • 190
  • Thanks for the fast answer. Yeah, didn't see it on the STYLE page: https://developer.mozilla.org/en/docs/Web/HTML/Element/style – Doug Sep 17 '14 at 12:40
  • 1
    its possible and mentioned here , https://developers.google.com/speed/docs/insights/OptimizeCSSDelivery – youhana Jan 15 '18 at 13:37
22

You could do this:

<link rel="stylesheet" href="/css/style.css" media="none" onload="if(media!=='all')media='all'" >

and create a noscript fallback

Gijs Erenstein
  • 810
  • 7
  • 13
13

As of Jan 2019, this StackOverflow post still ranks #1 in some Google searches. Therefore, I am submitting this very late answer for those who land here seeking to defer the loading of your CSS.

Credit: https://www.giftofspeed.com/defer-loading-css/


The gist

Add the following above the closing </body> tag of your html document

<script type="text/javascript">
  /* First CSS File */
  var giftofspeed = document.createElement('link');
  giftofspeed.rel = 'stylesheet';
  giftofspeed.href = '../css/yourcssfile.css';
  giftofspeed.type = 'text/css';
  var godefer = document.getElementsByTagName('link')[0];
  godefer.parentNode.insertBefore(giftofspeed, godefer);

  /* Second CSS File */
  var giftofspeed2 = document.createElement('link');
  giftofspeed2.rel = 'stylesheet';
  giftofspeed2.href = '../css/yourcssfile2.css';
  giftofspeed2.type = 'text/css';
  var godefer2 = document.getElementsByTagName('link')[0];
  godefer2.parentNode.insertBefore(giftofspeed2, godefer2);
</script>
Robert Shaw
  • 359
  • 2
  • 9
  • 3
    Please read carefully the docs, `defer` attribute must not be used if the src attribute is absent, this being the case of the solution proposed – Carlos J García Mar 01 '19 at 16:46
8

As of Sep 2020 i found that at least Chrome have native support to defer CSS with the attribute rel="preload" to make an async load of the file

<link href="main.css" rel="stylesheet" rel="preload" as="style"> 

You can use a more comprehensive approach using JavaScript to make it compatible with most browsers and include a noscript option when no JS is enabled

<link href="main.css" rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="main.css"></noscript>

source: https://web.dev/defer-non-critical-css/

siddharta
  • 139
  • 2
  • 9
2

I can't find it documented anywhere but my findings are:

How it was tested

  • Tested only with Google Chrome version 61.0.3163.100 (Official version) (64 bits)
  • Used Fast & Slow 3G throttling in dev tools.

What I tested

I have one stylesheet importing custom fonts and applying the fonts.

Before:

Text using the custom font was invisible until it was fully loaded and then it appeared.

After/Result:

So added => Result is that the text is visible immediately when the page is starting to render but using the fallback font, then after a while it switches to the custom font.

So it seems like at least Google Chrome supports defer on <link> tags as well even if it's not documented anywhere publicly...

OZZIE
  • 3,932
  • 3
  • 39
  • 51