Skip to content
Permalink
Browse files

feat(css): use PostCSS for processing CSS files

fix #354
  • Loading branch information
talha131 committed Dec 1, 2019
1 parent 1e90a5d commit 2b88865a36780257ac42173b949b5d7b4df516e9
@@ -0,0 +1,75 @@
Title: Use PostCSS To Compile CSS Stylesheets
Tags: postcss, gulp
Category: Contributing
Date: 2019-12-01 23:13
Slug: use-postcss-to-compile-css-stylesheets
Subtitle: Mandatory
Authors: Talha Mansoor
Summary:
Keywords:

Elegant uses [GulpJS](https://gulpjs.com/) and [PostCSS](https://postcss.org/) to do pre and post processing, like [adding vendor prefixes](https://github.com/postcss/autoprefixer) or [compressing the CSS file](https://cssnano.co/).

## Why not use Pelican assets plugin?

[Pelican's assets plugin](https://github.com/getpelican/pelican-plugins/tree/master/assets) uses [Python's webassets package](https://github.com/miracle2k/webassets).

Unfortunately, webassets have not had a release [since early 2017](https://github.com/miracle2k/webassets/releases). Requests to revive the project have [gone unheeded](https://github.com/miracle2k/webassets/issues/505).

I tired to install webassets from the Git repository to use its PostCSS filter but it didn't work. Instead of wasting time in wrestling the code of an unmaintained project, I decided to use PostCSS which is modern and actively maintained.

## How to use PostCSS

This is closely related to [LiveReload Elegant Documentation Using Gulp.js]({filename}./live-reload-gulp.md)

### Prerequisites

You need to run following steps only once, to setup the LiveReload using gulp.

#### Step 1: Install NodeJS and Yarn <!-- yaspeller ignore -->

Install [Node.js](https://nodejs.org/en/download/) and [Yarn](https://yarnpkg.com/en/docs/install) on your system.

If you are on Windows then try installing them with [scoop.sh](https://scoop.sh/). It saves time and makes update easier.

#### Step 2: Install gulp

Run this command from your command line terminal.

```bash
yarn global add gulp-cli
```

#### Step 3: Install Dependencies

In the root of the Elegant repository, run

```bash
yarn install
```

`yarn` will create `node_modules` folder in the root.

#### Step 4: Run `gulp`

In the root of the Elegant repository, run

```bash
gulp css
```

It will compile the CSS present in [`static/css`](https://github.com/Pelican-Elegant/elegant/tree/master/static/css) folder into `static/css/elegant.prod.css`.

To live preview your changes, use

```bash
gulp
```

## How does it work?

Gulp and PostCSS, takes all the CSS files present inside `static/css` folder. It applies PostCSS plugins on it like CSS compression.

It then writes the generated version in `static/css/elegant.prod.css` file. This is the file a Pelican blog uses when it uses Elegant theme.

If user has enabled [`assets` plugin]({filename}../Supported Plugins/assets-plugin.md), then this file is again made to go through webassets cssmin filter. Although this step is redundant because `elegant.prod.css` is already compressed. But it is necessary in case user has decided [to customize the theme using `custom.css`]({filename}../Advanced Features/custom-style.md). In which, assets cssmin filter will combine `elegant.prod.css` and `custom.css` into one file `style.min.css`.
@@ -18,6 +18,12 @@ essential to the proper look and feel of a properly designed website, the overhe
content being in separate files is that separate requests are made for each of them to the
server.

!!! Important

**Elegant comes with a compressed and concatenated CSS stylesheet**, so that only one request is made to fetch the CSS stylesheets. **Following instruction is redundant for most users.**

But if you have decided to [customize the theme using `custom.css`]({filename}../Advanced Features/custom-style.md) then follow these instruction.

Pelican provides a plugin that takes the various CSS and JavaScript files and compiles each
group of them into a single file. Not only does this process reduce the number of calls to
retrieve files from the server, but it minifies or reduces the overall size of
@@ -35,78 +41,3 @@ PLUGINS = ['assets']
!!! note

The [assets plugin](https://github.com/getpelican/pelican-plugins/blob/master/assets/Readme.rst) requires the Python `webassets` and `cssmin` packages to be installed.

## Debugging Notes

Note that you will not see the full power of the Assets Management plugin if you are working in
debug mode, that is building the website while using `--debug` on the Pelican command line.
In debug mode, some of the files may be minified into the `style.min.css` file, but the
original files will be included in the HTML page they are referenced from.

This will look something like the following:

```html
<link
rel="stylesheet"
href="http://localhost:8000/theme/webassets-external/f89ba5f14545a8fa0e81c1c6e2b5fc13_pygments.css"
/>
<link
rel="stylesheet"
href="http://localhost:8000/theme/webassets-external/96b04e88b0ba11363f4f2e2f59b5fb18_tipuesearch.css"
/>
<link
rel="stylesheet"
href="http://localhost:8000/theme/webassets-external/9c80344d72edcf2ebb95daecd6dfa24c_elegant.css"
/>
<link
rel="stylesheet"
href="http://localhost:8000/theme/webassets-external/d8877b08872b9883b67fbef219dfdebb_admonition.css"
/>
<link
rel="stylesheet"
href="http://localhost:8000/theme/webassets-external/78ddd4ea7393d1ac1fd9f91c21aa8b5f_custom.css"
/>
```

When the `--debug` command line option is removed, the lines described above will be
replaced with a line like:

```html
<link
rel="stylesheet"
href="https://jackdewinter.github.io/theme/css/style.min.css?c4027515"
/>
```

## Improving Elegant

If you are developing a new feature (for the theme or for your own website), you may need to
add a new CSS file to make sure that it renders properly on the webpage. Elegant ships with
the ability support
minification <!-- yaspeller ignore -->
of CSS files through the `minify_css.html` file. This file
is located in the `templates/_includes` directory of the theme and has the following
contents:

```text
{% assets filters="cssmin", output="css/style.min.css", "css/pygments.css", "tipuesearch/tipuesearch.css","css/elegant.css", "css/admonition.css", "css/custom.css" %}
<link rel="stylesheet" href="{{ SITEURL }}/{{ ASSET_URL }}">
{% endassets %}
```

To ensure that your new CSS file is minified, we advise you to follow one of these two
suggestions.

If you are planning to add a new feature to your own website, consider placing the changes in
the Elegant theme's `custom.css` file. This file is also located in the `templates/_includes`
directory, and is blank in a standard Elegant theme. As the `custom.css` file is already in
the list of files to minify, no addition modifications are required. If you are not sure
whether or not the feature will be submitted as part of Elegant, this is a good place to
start at.

If you are planning to add a new feature to Elegant and share it with others, you will be asked
to place any CSS changes for your feature in a new CSS file. This new file should be saved in
the theme's `templates/_includes` directory with the other CSS files. To ensure that the new
file is minified, a reference to it must be added to the first line of the `minify_css.html`
file, after the `css/admonition.css` file reference and before the `css/custom.css` file
reference.
@@ -27,7 +27,6 @@

PLUGIN_PATHS = ["plugins"]
PLUGINS = [
"assets",
"extract_toc",
"just_table",
"liquid_tags.img",
@@ -1,8 +1,13 @@
import fs from "fs";
import path from "path";
import { watch, parallel, series } from "gulp";
import { src, dest, watch, parallel, series } from "gulp";
import { exec } from "child_process";
import { create as browserSyncCreate } from "browser-sync";
import postcss from "gulp-postcss";
import cssnano from "cssnano";
import postcssPresetEnv from "postcss-preset-env";
import concat from "gulp-concat";

const browserSync = browserSyncCreate();

const path404 = path.join(__dirname, "documentation/output/404.html");
@@ -11,7 +16,7 @@ const content_404 = () =>

const cleanOutput = () => exec("cd documentation && rm -rf outout/");

const buildAll = () => exec("cd documentation && invoke build");
const buildContent = () => exec("cd documentation && invoke build");

const reload = cb => {
browserSync.init(
@@ -47,14 +52,46 @@ const watchFiles = () => {
"documentation/publishconf.py",
"templates/**/*.html",
"static/**/*.css",
"!static/**/elegant.prod.css",
"static/**/*.js"
],
{ ignoreInitial: false },
buildAll
);
};

const elegant = series(cleanOutput, buildAll, parallel(watchFiles, reload));
const pathProdCSS = path.join(__dirname, "static/css/elegant.prod.css");
const rmProdCSS = cb => {
if (fs.existsSync(pathProdCSS)) {
fs.unlinkSync(pathProdCSS);
}
cb();
};

const compileCSS = () => {
const plugins = [
// postcssPresetEnv comes with autoprefixer
postcssPresetEnv(),
cssnano()
];
return src([
"static/tipuesearch/tipuesearch.css",
"static/css/*.css",
"!static/css/elegant.prod.css"
])
.pipe(postcss(plugins))
.pipe(concat("elegant.prod.css"))
.pipe(dest("static/css/"));
};

const buildAll = series(rmProdCSS, compileCSS, buildContent);
const elegant = series(
compileCSS,
cleanOutput,
buildContent,
parallel(watchFiles, reload)
);

exports.css = series(rmProdCSS, compileCSS);
exports.elegant = elegant;
exports.default = elegant;
@@ -7,8 +7,12 @@
"babel-core": "^6.26.3",
"babel-preset-es2015": "^6.24.1",
"browser-sync": "^2.26.7",
"cssnano": "^4.1.10",
"cz-conventional-changelog": "3.0.2",
"gulp": "^4.0.2",
"gulp-concat": "^2.6.1",
"gulp-postcss": "^8.0.0",
"postcss-preset-env": "^6.7.0",
"semantic-release": "^15.13.31"
},
"config": {
@@ -20,5 +24,10 @@
"presets": [
"es2015"
]
}
},
"dependencies": {},
"browserslist": [
"defaults",
"IE 10"
]
}

Large diffs are not rendered by default.

@@ -1,11 +1,5 @@
{% assets filters="cssmin", output="css/style.min.css",
"css/pygments.css",
"tipuesearch/tipuesearch.css",
"css/elegant.css",
"css/typography.css",
"css/admonition.css",
"css/sidebar.css",
"css/sidebar-social.css",
"css/elegant.prod.css",
"css/custom.css" %}
<link rel="stylesheet" href="{{ SITEURL }}/{{ ASSET_URL }}">
{% endassets %}
@@ -37,10 +37,7 @@
{% if 'assets' in PLUGINS %}
{% include '_includes/minify_css.html' with context %}
{% else %}
<link rel="stylesheet" type="text/css" href="{{ SITEURL }}/theme/css/pygments.css" media="screen">
<link rel="stylesheet" type="text/css" href="{{ SITEURL }}/theme/tipuesearch/tipuesearch.css" media="screen">
<link rel="stylesheet" type="text/css" href="{{ SITEURL }}/theme/css/elegant.css" media="screen">
<link rel="stylesheet" type="text/css" href="{{ SITEURL }}/theme/css/admonition.css" media="screen">
<link rel="stylesheet" type="text/css" href="{{ SITEURL }}/theme/css/elegant.prod.css" media="screen">
<link rel="stylesheet" type="text/css" href="{{ SITEURL }}/theme/css/custom.css" media="screen">
{% endif %}
{% endblock head_links %}

0 comments on commit 2b88865

Please sign in to comment.
You can’t perform that action at this time.