Very recently, I started working on an HTML/CSS side project and I found myself in a state of panic. I haven't worked on plain HTML/CSS in a while. JavaScript has been part of my workflow for years and the output of that JavaScript was always a single page app.
In fact, I haven't worked on a static site in general in quite a while.
My NaΓ―ve Start
But I knew that such a workflow, despite being super simple, needed a toolchain I could use to speed up my development and more importantly, ensure the final output is bug-free, correct, and cross-browser compatible.
As I wrote my first index.html
, I thought immediately, "Ohhhh, I'm gonna need some templating". Nothing major, I just needed to include the header, footer, and a few other elements from other HTML files.
My first thought was to turn to PHP. I wrote quite a bit of PHP in my dev career and probably one of my favorite features of PHP was that it can be used as HTML on steroids with a simple include
.
So I'd have a header.php
:
<html>
<head>
<title>Whatever - don't care atm</title>
<link href="styles.css" ref="application/css" />
</head>
<body>
<nav><ul><li>home</li></ul></nav>
<?php
// index.php
include('./header.php');
?>
Page-specific content goes here!
<?php
include('./footer.php')
?>
And some footer.php
:
</body>
</html>
That way, if I change something about the page navigation, I don't have to go to numerous files to copy/paste that change.
Unfortunately, I don't have PHP installed but If I had to get it, I would.
Plus with PHP you get a slew of benefits:
- built-in programming language to generate lists for mocking stuff up
- more complicated
includes
if I wanted to -- for instance, convertingheader.php
into a function that takes templating variables as arguments - INSTANT "compilation" (eg. save, refresh and it works!)
The other problem I ran into was CSS. Plain CSS is fine but with SCSS, I could speed up my development and keep styles consistent throughout. Plus, I'd get to split my CSS into however many files I wanted to. That way, I'd define colors in variables, nest my selectors the way I like them and so on.
I figured I could do things the old-fashioned way (especially since I didn't know how to use native CSS vars):
/*---------------------
Variables:
main color: blue
secondary color: orange
nav grey: #444
*/
// Navigation section
.nav {
background-color: #444;
}
// Footer section
.footer {
}
.footer a {
color: blue;
}
You know, that could totally work but as I started to dread installing PHP, and using find/replace for updating "variables" in CSS, and then having one large CSS file for everything. And as my panic started to take over, I remembered Parcel.
Introducing Parcel
Parcel is a JavaScript bundler, at least that's what you've heard, right? That's it's kinda like Webpack?
Well, I'm not writing any JavaScript for this project (at least, I didn't plan to at this stage!).
Parcel is a very powerful compiling/process/whatever JavaScript tool that can automate your entire workflow and very easily. It's based on a zero-config ideology. It's not entirely zero-config but it has "sane" configs for 90% of use-cases.
When I used it for Preact, React, and TypeScript, I didn't have to do much of anything to make it work. Pretty much any config you want to add is more relevant to the tool itself than Parcel.
For instance, parcel automatically exposes your compiled results on localhost:1234
, it watches your files without being asked, and it'll alias Preact correctly to Babel for JSX compilation.
So I set off to figure out how to use Parcel for my use case and I promises myself to spend MINIMAL time on this because jumping into development was more important to me than a good workflow.
Basic Setup
The basic setup is dead simple. Because I don't want to use Parcel globally, I'll install it and all its plugins and dependencies, its transpilers and so on:
npm install parcel-bundler --save-dev
Yeah, that's it! And I'll go ahead and create a folder for my site called site
and setup an NPM script so we can use the local install:
mkdir site
touch site/index.html
And the scripts:
"scripts": {
"start": "parcel site/index.html
}
Just running npm start
will start your development flow where:
- everything is automatically watched
- files show up in
localhost:1234
- compiled files are in
dist
folder
SCSS compilation
I've used Parcel before which meant that I already knew it had great SASS/SCSS support. I remember the syntax better than LESS largely due to the fact that I worked on a couple of the Foundation projects and then I set it up at work so I worked with it more. Otherwise, I think the two are comparable (let's not start SASS/LESS wars).
The process is simple, install sass:
npm install sass --save-dev
And link to your scss file in your HTML:
<html>
<head>
<link href="styles.scss" type="text/css" />
</head>
</html>
You might have to restart parcel but it should "just work"TM.
Hmm, HTML templating?
Parcel doesn't include a templating engine. That's a GOOD thing. What it does include is PostHTML.
Now, I was worried about this part but after doing some research, it's what made me use Parcel. PostHTML is an HTML post-processor. Kind of like PostCSS.
Think of it as a tool that let's you do some really cool stuff with HTML. One of those things is using an include
syntax via a plugin! WHAT?
I REALLY wanted my PHP-like include
and that's what the posthtml-include
plugin gives us but via a more HTML-like syntax like so:
<include src="./partials/header.html"></include>
That was my WHOA moment. I looked at PostHTML plugins, and found a repository of AMAZING tools. I stuck to the include
plugin because it was the easiest and simplest. It kept me away from doing things "too smartly".
So to install it, you install the plugin
npm install posthtml-include --save-dev
and now you have to create your first piece of configuration. I want to point out that this is a config for posthtml
, not for Parcel. Create a .posthtmlrc.js
file and put this in there:
module.exports = {
plugins: {
'posthtml-include': {
root: __dirname + '/site',
}
}
}
This enables the plugin and tells you where the root of the project is.
What else?
Well, nothing. With this simple setup, I've got SCSS compiling, basic HTML includes, file watching, server running, and basically no configuration apart from one plugin needing to know the root of the project.
I think next time I set this up, I'll try using posthtml-modules which allows a sort of transclusion
or "content projection" similar to what Angular and AngularJS do. Like so:
<!-- index file -->
<module href="./module.html">
Content to transclude
</module>
<!-- module file -->
Here is my special content:
<pre>
<content></content>
</pre>
<!-- resulting index file -->
Here is my special content:
<pre>
Content to transclude
</pre>
The other option is to use posthtml-expressions which does true templating; however, I'm still not a 100% sold on having a huge list of variables in my config. On the other hand, it'd bring us closer to
What about JavaScript?
And here's the thing...I realized I need some JS in the project after I got started. I need to have sticky dropdowns (click to reveal menu instead of hover), and a slider. Both are possible with CSS; however, not only is that a little beyond me, but I also think that would be rather unmaintainable.
So...I don't have to do much at this point except just include a JS script tag in the index.html
file. And start coding.
Like this article? Follow me on Twitter or checkout my blog
Top comments (3)
great tips. I also tried Parcel. didnt know about the post-html includes though. Parcel such a powerful tool for super quick prototyping and fast start.
Hi, i suggest you to use PostCSS over sass because it works very well with post-html and it allow you to use postcss-modules (amd other plugins) that bring css namespacing like CSS modules.
That's a great idea! My goal was to setup quickly and I was very familiar with both SCSS and LESS. I've tried PostCSS a couple of times before but did not feel confident in trying to set it up for this project.