Skip to content

Commit

Permalink
Remove inlined CSS rules from source stylesheets #39
Browse files Browse the repository at this point in the history
  • Loading branch information
bezoerb committed Oct 22, 2014
1 parent a93bcb4 commit 6f97f8a
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 12 deletions.
4 changes: 3 additions & 1 deletion .gitignore
@@ -1,3 +1,5 @@
node_modules

fixture/test-*
fixture/test-*
fixture/styles/main.9a350a2d.css
fixture/bower_components/bootstrap/dist/css/bootstrap.3ce13c6c.css
18 changes: 11 additions & 7 deletions README.md
Expand Up @@ -35,27 +35,30 @@ var critical = require('critical');
critical.generateInline({
// Your base directory
base: 'dist/',

// HTML source
src: 'index.html',

// Your CSS Files (optional)
css: ['dist/styles/main.css'],

// Viewport width
width: 320,

// Viewport height
height: 480,

// Target for final HTML output
htmlTarget: 'index-critical.html',

// Target for generated critical-path CSS (which we inline)
styleTarget: 'styles/main.css',

// Minify critical-path CSS when inlining
minify: true
minify: true,

// Extract inlined styles from referenced stylesheets
extract: true
});
```

Expand Down Expand Up @@ -145,6 +148,7 @@ critical.inline({
| width | `integer` | (Generation only) Width of the target viewport |
| height | `integer` | (Generation only) Height of the target viewport |
| minify | `boolean` | Enable minification of CSS output |
| extract | `boolean` | Remove the inlined styles from any stylesheets referenced in the HTML. It generates new references based on extracted content so it's save to use for multiple HTML files referencing the same stylesheet|
| styleTarget | `string` | (`generateInline` only) Destination for critical-path styles |
| htmlTarget | `string` | (`generateInline` only) Destination for (critical-path CSS) style-inlined HTML |
| inlineImages | `boolean` | Inline images (default: false)
Expand Down
97 changes: 97 additions & 0 deletions fixture/index-inlined-async-extracted-final.html
@@ -0,0 +1,97 @@
<!doctype html>
<html class="no-js">
<head>
<meta charset="utf-8">
<title>critical css test</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Place favicon.ico and apple-touch-icon.png in the root directory -->

<!-- build:css styles/main.css -->
<style type="text/css">
body{padding-top:20px;padding-bottom:20px}.header{padding-left:15px;padding-right:15px;border-bottom:1px solid #e5e5e5}.header h3{margin-top:0;margin-bottom:0;line-height:40px;padding-bottom:19px}.jumbotron{text-align:center;border-bottom:1px solid #e5e5e5}.jumbotron .btn{font-size:21px;padding:14px 24px}@media screen and (min-width:768px){.container{max-width:730px}.header{padding-left:0;padding-right:0;margin-bottom:30px}.jumbotron{border-bottom:0}}html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a{background:0 0}h1{margin:.67em 0}@media print{*{color:#000!important;text-shadow:none!important;background:0 0!important;box-shadow:none!important}a{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}a[href^="#"]:after{content:""}h3,p{orphans:3;widows:3}h3{page-break-after:avoid}}*,:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:62.5%;-webkit-tap-highlight-color:transparent}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}a{color:#428bca;text-decoration:none}h1,h3{font-family:inherit;font-weight:500;line-height:1.1;color:inherit;margin-top:20px;margin-bottom:10px}h1{font-size:36px}h3{font-size:24px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:200;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.text-muted{color:#999}ul{margin-top:0;margin-bottom:10px}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-lg{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a{color:#fff;background-color:#428bca}.jumbotron{padding:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.container .jumbotron{border-radius:6px}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron{padding-right:60px;padding-left:60px}.jumbotron h1{font-size:63px}}.container:after,.container:before,.nav:after,.nav:before{display:table;content:" "}.container:after,.nav:after{clear:both}.pull-right{float:right!important}
</style>
<noscript>
<link rel="stylesheet" href="styles/main.9a350a2d.css">
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.3ce13c6c.css">
</noscript>

<!-- endbuild -->

</head>
<body>
<!--[if lt IE 10]>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
<![endif]-->

<div class="container">
<div class="header">
<ul class="nav nav-pills pull-right">
<li class="active"><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
</ul>
<h3 class="text-muted">critical css test</h3>
</div>

<div class="jumbotron">
<h1>&apos;Allo, &apos;Allo!</h1>
<p class="lead">Always a pleasure scaffolding your apps.</p>
<p><a class="btn btn-lg btn-success" href="#">Splendid!</a></p>
</div>

<div class="row marketing">
<div class="col-lg-6">
<h4>HTML5 Boilerplate</h4>
<p>HTML5 Boilerplate is a professional front-end template for building fast, robust, and adaptable web apps or sites.</p>

<h4>Bootstrap</h4>
<p>Sleek, intuitive, and powerful mobile first front-end framework for faster and easier web development.</p>
</div>
</div>

<div class="footer">
<p>&#x2665; from the Yeoman team</p>
</div>
</div>

<!-- Google Analytics: change UA-XXXXX-X to be your site's ID. -->
<script>
(function(b,o,i,l,e,r){b.GoogleAnalyticsObject=l;b[l]||(b[l]=
function(){(b[l].q=b[l].q||[]).push(arguments)});b[l].l=+new Date;
e=o.createElement(i);r=o.getElementsByTagName(i)[0];
e.src='//www.google-analytics.com/analytics.js';
r.parentNode.insertBefore(e,r)}(window,document,'script','ga'));
ga('create','UA-XXXXX-X');ga('send','pageview');
</script>

<!-- build:js scripts/vendor.js -->
<!-- bower:js -->
<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/bootstrap/dist/js/bootstrap.js"></script>
<!-- endbower -->
<!-- endbuild -->

<!-- build:js scripts/plugins.js -->
<script src="bower_components/bootstrap/js/affix.js"></script>
<script src="bower_components/bootstrap/js/alert.js"></script>
<script src="bower_components/bootstrap/js/dropdown.js"></script>
<script src="bower_components/bootstrap/js/tooltip.js"></script>
<script src="bower_components/bootstrap/js/modal.js"></script>
<script src="bower_components/bootstrap/js/transition.js"></script>
<script src="bower_components/bootstrap/js/button.js"></script>
<script src="bower_components/bootstrap/js/popover.js"></script>
<script src="bower_components/bootstrap/js/carousel.js"></script>
<script src="bower_components/bootstrap/js/scrollspy.js"></script>
<script src="bower_components/bootstrap/js/collapse.js"></script>
<script src="bower_components/bootstrap/js/tab.js"></script>
<!-- endbuild -->

<!-- build:js scripts/main.js -->
<script src="scripts/main.js"></script>
<!-- endbuild -->
<script>
(function(d,u){for (var i in u) {var l=d.createElement('link');var r=d.getElementsByTagName('script')[0];l.type='text/css';l.rel='stylesheet';l.media='only x';l.href=u[i];r.parentNode.insertBefore(l,r);(function(l){setTimeout( function(){l.media='all';});})(l)}}(document,['styles/main.9a350a2d.css','bower_components/bootstrap/dist/css/bootstrap.3ce13c6c.css']));
</script>
</body>
</html>
6 changes: 5 additions & 1 deletion index.js
Expand Up @@ -214,7 +214,11 @@ exports.generateInline = function (opts, cb) {
// Inline generated css
fs.readFileAsync(path.join(opts.base, opts.src))
.then(function (html) {
return sourceInliner(html, output, opts.minify);
return sourceInliner(html, output, {
minify: opts.minify || false,
extract: opts.extract || false,
basePath: opts.base || process.cwd()
});
}).then(function (final) {
if (opts.htmlTarget) {
return fs.writeFileAsync(path.join(opts.base, opts.htmlTarget), final).then(function () {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -26,7 +26,7 @@
"cheerio": "^0.17.0",
"clean-css": "^2.2.4",
"imageinliner": "^0.2.2",
"inline-critical": "0.0.4",
"inline-critical": "0.0.5",
"oust": "^0.2.0",
"penthouse": "^0.2.5",
"slash": "^1.0.0",
Expand Down
20 changes: 18 additions & 2 deletions test.js
@@ -1,6 +1,6 @@
/*
Unit tests for Critical.
Note: At present, our tests will pass on Unix based systems but fail on
Windows. This is a known issue to do with line-endings which we hope to
address in the very near future.
Expand Down Expand Up @@ -322,4 +322,20 @@ it('does not screw up width win32 paths', function (done) {
);
done();
});
});
});

it('inlines and extracts critical-path CSS', function (done) {
var expected = fs.readFileSync('fixture/index-inlined-async-extracted-final.html', 'utf8');

critical.generateInline({
base: 'fixture/',
minify: true,
extract: true,
src: 'index.html',
htmlTarget: 'test-inlined-async-extracted-final.html'
}, function (err, output) {
var out = fs.readFileSync('fixture/test-inlined-async-extracted-final.html', 'utf8');
assert.strictEqual(stripWhitespace(out), stripWhitespace(expected));
done();
});
});

0 comments on commit 6f97f8a

Please sign in to comment.