Reputation:
Basically I am wondering what is the advantage / purpose of using @import
to import stylesheets into an existing stylesheet versus just adding another ...
<link rel="stylesheet" type="text/css" href="" />
to the head of the document?
Upvotes: 330
Views: 402062
Reputation: 15789
@import
and external Cascading Style Sheets in your Website!Updated: 8/22/2022
(There has been a lot of false information posted on the web the past 10 years about the use of @import
I intend to correct. So please read my information carefully below.)
Rule Number One
Never Rely on JavaScript API's or Tricks to Manage Cascading Style Sheets!! Do NOT rely on 3rd party vendor CSS solutions! Never use SASS, React, Modernizr, Bootstrap, or Angular to manage CSS. I know, I have used them all. Always manage Cascading Style Sheets yourself using hand-written CSS text files and your site will not only run faster, but you will have total control over your websites design and your user experience. If you rely on these poorly designed systems they will fail in numerous scenarios, slow down your site, and fail in numerous versions of older browsers...too many to count.
Rule Number Two
Yes, always use @import
! It works GREAT as a modern solution to using CSS. I highly recommend it! Its been used for over 20+ years in hundreds of browsers with no problems. There are false assumptions about @import
that many younger, inexperienced developers have made about, including that @import
"blocks" downloads of web page scripts, HTML, or other assets during a typical page request. These are completely false. I will prove it below!
Rule Number Three
Use of @import
in your CSS does NOT slow down page load or parsing. Multiple @imports
combined in an embedded <style>
element all download in parallel to each other. (That is true even for very old IE browsers). In the case of multiple @import
rules called from inside a <link>
external style sheet, these also all download in parallel and use the same connection as the parent style sheet that holds them. They just do not download in parallel to the parent sheet and any CSS it might include. More on that later.
Rule Number Four
CSS does NOT need to be compressed, minimized, preprocessed, etc. And CSS download size, or multiple external CSS files using @import is NOT a problem on the Web. Most style sheets are rarely over 30 kilobytes
in size. Compare this to the 1-5 Megabytes in a typical JavaScript API library
, which is a bandwidth hog, and you will see why CSS downloads do not delay or slow down browser content. Make sure you realize that fact. These tiny imported sheets of style text is a fragment of the much larger download footprint of a typical web page download, which explodes in size when using these modern JavaScript libraries, emoticons, images, videos, and media files shoved into the block stream of a typical user's browser during a modern web page display request. That is why you also should never compress your CSS or preprocess it using SASS as the savings in download time or parsing and render-tree display are almost zero.
Blocking CSS is not the problem, and @import is not a bug or an outdated technology. It is a very reliable, older coding solution that has worked fine for over 20 years.
But you still may wonder how can @import
truly help me?
Let's look at an example. Most developers import external style sheets to divide up sections of styles they either want to manage in modules or to hide from certain browsers. In this linked sheet below, all imported sheets are added to a single parent style sheet to manage them in one location. When the linked sheet is parsed during HTML download by the browser, a connection is open (or reused) and all these imported sheets download in parallel to each other over the connection. So, we would add the parent sheet to hold our imported external CSS sheets as follows:
<link media="screen" rel="stylesheet" type="text/css" href="parent.css" />
...then inside the parent.css sheet above we have the following @import
children. They all should download in parallel and in most browsers and share the same TCP connection. Most modern web browsers have 6 or more, so that means CSS will never block HTML or other page downloads and parsing. Plus, many servers in 2022 now support HTTP2 that includes Multiplexing which means all these tiny CSS file downloads can now share a single connection with other requests. These small text files download FAST in modern browser using @import
!
@import url('child1.css');
@import url('child2.css');
@import url('child3.css');
@import url('child4.css');
In the second example below, these @import
declarations embedded in an HTML <style>
tag should also all download in parallel to each other, just randomly. Again, this worked this way in many older browsers, as well as newer ones. From what I have read, they might have order issues using @import
like this, but your CSS should rarely be dependent on cascade order in this type of design. By the way, there are numerous formats for writing @import
. Use the format @import url('mycss.css');
when writing this type of media query to improve the chances your modern HTML5 browser will parse your import file CSS code reliably:
<style>
@import url('child1.css');
@import url('child2.css');
@import url('child3.css');
@import url('child4.css');
</style>
The ONLY time @import
does have issues is the following limited scenarios:
@import
and linked CSS in combination fail to download in parallel. This would affect <link>
CSS downloads, too, so this isn't a real case against @import
.<link>
parent style sheet holds imported sheets, because the parent sheet has to connect and parse its CSS file first, it adds one extra connection to the server. That makes logical sense and should be expected. If your sheet only has imports and no CSS, which I recommend, with no CSS to parse, @import begins immediately and should use the same connection to download the file as the parent.<link>
parent style sheet holds multiple imported sheets, IF the parent sheet also has additional CSS after the @imports declarations, then yes there would be a true "blocking" CSS connection. In that one case the parent CSS file has to be downloaded first, complete its CSS parsing and download first, discover the @imports, THEN download the @import styles and place them before the CSS in the file before the file is complete. This makes logical sense and why you should NEVER combine CSS with @import
style rules in any CSS style sheet. I never do that. If you remove the CSS in the parent file, imports immediately call down their files over the parent files connection without delay.<link>
style sheet that has no imported rules with either a linked style sheet with an @import
or an embedded <style>
with @import
, in Internet Explorer ONLY, they generally wont download in parallel. The other browsers manage this fine. As mentioned this may be related to IE's limited browser connections.So, based on these rules, in most situations, @import works fine. The main gotcha is when adding @import into a sheet with a lot of plain CSS. That type of thing makes sense and would cause a long delay as the parent parses its own CSS then discovers additional @imports
.
Keep in mind modern browsers have around 6 available connections so @import
would not be the bottleneck, having too many files or too many LARGE files plus non-async JavaScript would be what's blocking parsing and rendering in your web pages. BTW, your typical JavaScript API download now is 1.5 Megabytes!
There are also many GOOD reasons to use @import!
One powerful reason for using @import is to do cross-browser design. Imported sheets, in general, are hidden from many older browsers, which allows you to apply specific formatting for very old browsers like Netscape 4 or older series, Internet Explorer 5.2 for Mac, Opera 6 and older, and IE 3 and 4 for PC....then using @import
add a modern style sheet these browsers cannot see because many older browsers do not recognize certain versions of @import
.
Example, add a normal style sheet seen by all browsers, old and new:
<link media="screen" rel="stylesheet" type="text/css" href="styles.css" />
...with this CSS inside...
body {
font-size:13px;
}
Now, in your imported custom sheet (newerbrowsers.css) simply apply the newer style to write over the above one for newer browsers only. The newer browser use "em" units, the older ones "px". This version of @import
below is not seen by a wide range of older browsers, including IE 1-7, MAC IE 5, Netscape 4, and many others:
<link media="screen" rel="stylesheet" type="text/css" href="newerbrowsers.css" />
...with this @import inside only newer browsers will see. Using this @import format with 'all', it will be hidden from IE1-7 browsers, and many more!
@import 'imported.css' all;
...with this CSS in the @import...
html body {
font-size:1em;
}
Using "em" units is superior to "px" units as it allows both the fonts and design to stretch based on user settings, where as older browsers do better with pixel-based (which are rigid and cannot be changed in browser user settings). The imported sheet would not be seen by most older browsers.
The above @import
sheet rule I posted above is now hidden from all these old browsers listed below, which you can now style separately or completely ignore, freeing your team to now design for modern HTML5 browsers!
- Netscape 1-4.8
- Opera 1-3.5
- Windows Internet Explorer 1-7.x
- Macintosh Internet Explorer 2-4.5
- Konqueror 1-2.1
- Windows Amaya 1-5.1
- iCab 1-2
- OmniWeb
- Many more antiquated browsers...
You may say, "who cares about older browsers!" Try going to some larger antiquated government or corporate network with thousands of old Windows PC's or Mac's and you will still see those older browsers being used! But its really just good design, because the browser you love today will also someday be antiquated and outdated as well. And using CSS in a limited way means you now have an even larger and growing group of user-agents that don't work well with you site.
Using @import
, your cross-browser web site compatibility will now reach 99.99% positive web browser display saturation simply because so many browsers understand imported sheets. You can also manage CSS linked CSS for the older browsers and use imported CSS to manage all your newer browser styles and layouts using my solution above. It guarantees you apply basic CSS for older agents, but more advanced CSS3+ is delivered to newer ones. This allows content to be accessible for older browsers without compromising rich visual displays needed in newer desktop browsers or having to manage hundreds of complex CSS hacks and fixes for various browser versions.
Remember also that modern browsers cache HTML structures and CSS extremely well after the first call to a web site. That's the whole purpose in using linked and imported external CSS. One call, one cache! Besides, multiple calls to the server is not the bottleneck it once was, anyway. Megabytes and megabytes of Javascript API's and JSON uploaded to smart devices and poorly designed HTML markup that is not consistent between pages is the main driver of slow rendering today. For example, do a viewsource on many Google website pages and download all the megabytes and megabytes of sync'ed and async'ed JavaScript that comes with it! Your average Google news page is well over 6 megabytes of ECMAScript just to render a tiny bit of text! Bad!!
A few kilobytes of cached CSS and consistent clean HTML with smaller Javascript footprints will render in a user-agent in lightning speed simply because the browser caches external files, markup, and CSS one time, the first time. Do not manipulate and change the natural parsing flow of your website using huge Javascript circus tricks. Rely on tiny CSS files you create yourself, download them using @import, and your site will display perfectly every time.
By the way, if you want to see examples of how to use cross-browser CSS this way, you may download my CSS framework here: Universal CSS Framework
Upvotes: 34
Reputation: 6075
(2022 Update: I should note that, many professional developers now manage their CSS with a system like SASS, or frameworks compatible with React, either of which would handle these optimizations internally.)
(2023 Update: Alternatively, utility class frameworks like Tailwind have started to become popular, which would reduce the amount of CSS you would write in the first place.)
I'm going to play devil's advocate, because I hate it when people agree too much.
There are two variables you're optimizing for at any given time - the performance of your code, and the performance of the developer. In many, if not a majority of cases, it's more important to make the developer more efficient, and only then make the code more performant.
If you have one stylesheet that depends on another, the most logical thing to do is to put them in two separate files and use @import. That will make the most logical sense to the next person who looks at the code.
When would such a dependency happen? It's pretty rare, in my opinion - usually one stylesheet is enough. However, there are some logical places to put things in different CSS files:
- Theming: If you have different color schemes or themes for the same page, they may share some, but not all components.
- Subcomponents: A contrived example - say you have a restaurant page that includes a menu. If the menu is very different from the rest of the page, it'll be easier to maintain if it's in its own file.
Usually stylesheets are independent, so it's reasonable to include them all using <link href>
. However, if they are a dependent hierarchy, you should do the thing that makes the most logical sense to do.
Python uses import; C uses include; JavaScript has require. CSS has import; when you need it, use it!
Multiple CSS requests of any kind - whether through links or through @imports - are bad practice for high performance web sites. Once you're at the point where optimization matters, all your CSS should be flowing through a minifier. Cssmin combines import statements; as @Brandon points out, grunt has multiple options for doing so as well. (See also this question).
Once you're at the minified stage, <link>
is faster, as people have pointed out, so at most link to a few stylesheets and don't @import any if at all possible.
Before the site reaches production scale though, it's more important that the code is organized and logical, than that it goes slightly faster.
Upvotes: 216
Reputation: 329
Modern browsers can use a css file to define global variables. This file can be imported into other css files which can use the variables.
For example, to have consistent colors across a site:
colors.css
:root {
--bg-dark: #ffffff;
}
home.css
@import "colors.css";
body: var(--bg-dark)
Upvotes: 2
Reputation: 1021
This might help a PHP developer out. The below functions will strip white space, remove comments, and concatenate of all your CSS files. Then insert it into a <style>
tag in the head before page load.
The function below will strip comments and minify the passed in css. It is paired in conjunction with the next function.
<?php
function minifyCSS($string)
{
// Minify CSS and strip comments
# Strips Comments
$string = preg_replace('!/\*.*?\*/!s','', $string);
$string = preg_replace('/\n\s*\n/',"\n", $string);
# Minifies
$string = preg_replace('/[\n\r \t]/',' ', $string);
$string = preg_replace('/ +/',' ', $string);
$string = preg_replace('/ ?([,:;{}]) ?/','$1',$string);
# Remove semicolon
$string = preg_replace('/;}/','}',$string);
# Return Minified CSS
return $string;
}
?>
You will call this function in the head of your document.
<?php
function concatenateCSS($cssFiles)
{
// Load all relevant css files
# concatenate all relevant css files
$css = '';
foreach ($cssFiles as $cssFile)
{
$css = $css . file_get_contents("$cssFile.css");
}
# minify all css
$css = minifyCSS($css);
echo "<style>$css</style>";
}
?>
Include the function concatenateCSS()
in your document head. Pass in an array with the names of your stylesheets with its path IE: css/styles.css
. You are not required to add the extension .css
as it is added automatically in the function above.
<head>
<title></title>
<?php
$stylesheets = array(
"bootstrap/css/bootstrap.min",
"css/owl-carousel.min",
"css/style"
);
concatenateCSS( $stylesheets );
?>
</head>
Upvotes: -2
Reputation: 31
Sometimes you have to use @import as opposed to inline . If you are working on a complex application that has 32 or more css files and you must support IE9 there is no choice. IE9 ignores any css file after the first 31 and this includes and inline css. However, each sheet can import 31 others.
Upvotes: 3
Reputation: 139
There is almost no reason to use @import as it loads every single imported CSS file separately and can slow your site down significantly. If you are interested in the optimal way to deal with CSS(when it comes to page speed), this is how you should deal with all your CSS code:
More detailed information here: http://www.giftofspeed.com/optimize-css-delivery/
The reason the above works best is because it creates less requests for the browser to deal with and it can immediately start rendering the CSS instead of downloading separate files.
Upvotes: -2
Reputation: 21
I think @import is most useful when writing code for multiple devices. Include a conditional statement to only include the style for the device in question, then only one sheet gets loaded. You can still use the link tag to add any common style elements.
Upvotes: 2
Reputation: 2869
Quoted from http://webdesign.about.com/od/beginningcss/f/css_import_link.htm
The main purpose of @import method is to use multiple style sheets on a page, but only one link in your < head >. For example, a corporation might have a global style sheet for every page on the site, with sub-sections having additional styles that only apply to that sub-section. By linking to the sub-section style sheet and importing the global styles at the top of that style sheet, you don't have to maintain a gigantic style sheet with all the styles for the site and every sub-section. The only requirement is that any @import rules need to come before the rest of your style rules. And remember that inheritance can still be a problem.
Upvotes: 4
Reputation: 12916
It is best to NOT use @import
to include CSS in a page for speed reasons. See this excellent article to learn why not: http://www.stevesouders.com/blog/2009/04/09/dont-use-import/
Also it is often harder to minify and combine css files that are served via the @import tag, because minify scripts cannot "peel out" the @import lines from other css files. When you include them as <link tags you can use existing minify php/dotnet/java modules to do the minification.
So: use <link />
instead of @import
.
Upvotes: 13
Reputation: 21
Use @import in your CSS if you are using a CSS RESET, like Eric Meyer's Reset CSS v2.0, so it does it's job before applying your CSS, thus preventing conflicts.
Upvotes: 2
Reputation: 2085
@Nebo Iznad Mišo Grgur
The following are all correct ways to use @import
@import url("fineprint.css") print;
@import url("bluish.css") projection, tv;
@import 'custom.css';
@import url("chrome://communicator/skin/");
@import "common.css" screen, projection;
@import url('landscape.css') screen and (orientation:landscape);
source: https://developer.mozilla.org/en-US/docs/Web/CSS/@import
Upvotes: 11
Reputation: 2085
One place where I use @import is when I'm doing two versions of a page, English and French. I'll build out my page in English, using a main.css. When I build out the French version, I'll link to a French stylesheet (main_fr.css). At the top of the French stylesheet, I'll import the main.css, and then redefine specific rules for just the parts I need different in the French version.
Upvotes: 4
Reputation:
From a page speed standpoint, @import
from a CSS file should almost never be used, as it can prevent stylesheets from being downloaded concurrently. For instance, if stylesheet A contains the text:
@import url("stylesheetB.css");
then the download of the second stylesheet may not start until the first stylesheet has been downloaded. If, on the other hand, both stylesheets are referenced in <link>
elements in the main HTML page, both can be downloaded at the same time. If both stylesheets are always loaded together, it can also be helpful to simply combine them into a single file.
There are occasionally situations where @import
is appropriate, but they are generally the exception, not the rule.
Upvotes: 363
Reputation: 471
I experienced a "high peak" of linked stylesheets you can add. While adding any number of linked Javascript wasn't a problem for my free host provider, after doubling number of external stylesheets I got a crash/slow down. And the right code example is:
@import 'stylesheetB.css';
So, I find it useful for having a good mental map, as Nitram mentioned, while still at hard-coding the design. Godspeed. And I pardon for English grammatical mistakes, if any.
Upvotes: 0
Reputation: 16157
They are very similar. Some may argue that @import is more maintainable. However, each @import will cost you a new HTTP request in the same fashion as using the "link" method. So in the context of speed it is no faster. And as "duskwuff" said, it doesn't load simultaneously which is a downfall.
Upvotes: 3
Reputation: 2869
using the link method, the stylesheets are loaded parallel (faster and better), and nearly all browsers support link
import loads any extra css files one-by-one (slower), and could give you Flash Of Unstyled Content
Upvotes: 13
Reputation: 6716
I think the key in this are the two reasons why you are actually writing multiple CSS style sheets.
For the first reason the additional <link>
tag would apply as this allows you to load different set of CSS files for different pages.
For the second reason the @import
statement appears as the most handy because you get multiple CSS files but the files loaded are always the same.
From the perspective of the loading time there is no different. The browser has to check and download the seperated CSS files no matter how they are implemented.
Upvotes: 3
Reputation: 82267
There is not really much difference in adding a css stylesheet in the head versus using the import functionality. Using @import
is generally used for chaining stylesheets so that one can be easily extended. It could be used to easily swap different color layouts for example in conjunction with some general css definitions. I would say the main advantage / purpose is extensibility.
I agree with xbonez comment as well in that portability and maintainability are added benefits.
Upvotes: 7