Skip to content

Commit

Permalink
Add SVG sprite inline in HTML, amend README
Browse files Browse the repository at this point in the history
  • Loading branch information
einomi committed Apr 23, 2022
1 parent 6b1ce88 commit 2130b10
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 56 deletions.
11 changes: 11 additions & 0 deletions .eleventy.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const { RemoteAssetCache } = require('@11ty/eleventy-cache-assets');
const sizeOf = require('image-size');

const generateImageHTML = require('./generate-image-html');
const fs = require('fs');

function imageShortcode(src, attributes = {}, maxWidth = 2636) {
console.log('src', src);
Expand Down Expand Up @@ -63,6 +64,15 @@ function imageShortcode(src, attributes = {}, maxWidth = 2636) {
return generateImageHTML(metadata, imageAttributes);
}

function inlineSvgSprite() {
try {
return fs.readFileSync('./dist/svg/sprite.svg', 'utf8');
} catch (error) {
console.warn("SVG Sprite file doesn't exist");
}
return '';
}

module.exports = (eleventyConfig) => {
eleventyConfig.addPassthroughCopy({ 'src/public': '/' });

Expand All @@ -77,6 +87,7 @@ module.exports = (eleventyConfig) => {
});

eleventyConfig.addNunjucksShortcode('image', imageShortcode);
eleventyConfig.addNunjucksShortcode('svg_sprite', inlineSvgSprite);

return {
dir: {
Expand Down
50 changes: 26 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,18 @@ This is a production-ready starter that features Nunjucks, SASS, TailwindCSS (wi

11ty is responsible for building HTML only, the rest is built with Gulp.

Can be used in conjunction with any data source either a headless CMS, JSON, markdown, or any other data source that has a JS API. Please see [11ty documentation](https://www.11ty.dev/docs/data/) on data source matter
Can be used in conjunction with any data source either a headless CMS, JSON, markdown, or any other data source that has a possibility to fetch data using JavaScript. Please see [11ty documentation](https://www.11ty.dev/docs/data/) on data source matter.

## Getting started

#### 1. Install dependencies:

With `yarn`

```
yarn install
```

or with `npm`:

```
npm install
```

#### 2. Run the project for development:

```
yarn start
```

or

```
npm start
```
Expand All @@ -44,19 +30,19 @@ npm start
#### Running the project for development:

```
yarn start
npm start
```

#### Build the project for production:

```
yarn build
npm run build
```

#### Creating a production-ready zip-archive `build.zip`:

```
yarn zip
npm run zip
```

## Folder Structure
Expand Down Expand Up @@ -85,29 +71,37 @@ This starter features Webpack v5 for building JS bundle.

## Customize static path

This template allows you to customize static path to project resources such as images, scripts, styles, etc. Add an `.env` file to the root directory of the project with the following content `STATIC_PATH=http://localhost:9000` and use _STATIC_PATH_ like `<link rel="stylesheet" href="{{ STATIC_PATH }}/css/tailwind.css">`
This template allows you to customize static path of project resources such as images, scripts, styles, etc. Add an `.env` file to the root directory of the project with the following content `STATIC_PATH=http://localhost:9000` and use _STATIC_PATH_ like `<link rel="stylesheet" href="{{ STATIC_PATH }}/css/tailwind.css">`

**Keep mind:** To use _STATIC_PATH_ in macros, it must be passed as props

## The SVG sprite

It is possible to automatically keep your SVG files for the project inside a single SVG sprite with the [gulp-svgstore](https://github.com/w0rm/gulp-svgstore) plugin. So that it's better to add SVG files to the project in the following way:
It is possible to store SVG files inside a single SVG sprite. The starter uses the [gulp-svgstore](https://github.com/w0rm/gulp-svgstore) plugin to generate a sprite. SVG sprites technique is the recommended approach for adding vector images to the project.

The SVG sprite markup is inlined in `base.njk` template using `{% svg_prite %}` shortcode function (there is no need to modify this code).

To display an SVG image on the page, first add if to the `src/svg` folder. Let's suppose that this file would have the name `some-vector.svg`.

Then add it to the page in the following way:

```
<svg><use xlink:href="/svg/sprite.svg#icon-some-vector-image"></use></svg>
<svg><use xlink:href="#icon-some-vector"></use></svg>
```

Keep in mind that, in doing so, the SVG file `some-vector-image.svg` should be located in the `src/svg` directory. You can also set, for example, `fill` or `stroke` for this element on the page by using CSS selectors (so without setting them inside the SVG file).
**Keep mind:** `some-vector.svg` file should be located in the `src/svg` directory so that `gulp-svgstore` could add it to the SVG sprite.

You can also set, for example, `fill` or `stroke` for this element on the page by using CSS selectors (so without setting them inside the SVG file). It is also possible to animate SVG element parts (like `<path>`, `<circle>`, etc).

See examples in the index.njk
You can also take a look at the `<svg>` examples in the index.njk.

## {% image %} Nunjucks tag

This tag allows generating AVIF and WebP images. It also creates srcset sizes automatically based on the given max width (the 3rd argument) and widths in the `.eleventy.js` config file.

## Inlining raster or svg images into HTML

<b>Attention!</b> The files, which should be inlined, have to seat in the `src/images/inline` directory.
<b>Attention!</b> The files, which should be inlined, have to be placed into the `src/images/inline` folder.

### Inlining raster or svg images in CSS

Expand All @@ -131,12 +125,20 @@ height: height('some-image.png')
background-size: size('some-image.png')
```

<b>Attention!</b> Please use this feature with caution as it may bloat the final `CSS` file. Inlining images could be a good approach if the file is quite small, in other cases prefer `{% image %}` tag.

### Inlining images inside Nunjucks templates

```
<img src="{% inline 'some-image.png' %}" alt="Some image" />
```

<b>Attention!</b> Please use this feature with caution as it may bloat the final `HTML` file. Inlining images could be a good approach if the file is quite small, in other cases prefer `{% image %}` tag.

## Useful links

[Nunjucks syntax](https://mozilla.github.io/nunjucks/templating.html).

[TailwindCSS](https://tailwindcss.com/)

[TailwindCSS Cheatsheet](https://nerdcave.com/tailwind-cheat-sheet)
15 changes: 13 additions & 2 deletions gulp-tasks/svg.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
const path = require('path');

const gulp = require('gulp');
const rename = require('gulp-rename');
const svgstore = require('gulp-svgstore');
const svgmin = require('gulp-svgmin');
const path = require('path');
const cheerio = require('gulp-cheerio');

const PATHS = require('../paths');

Expand All @@ -22,7 +24,7 @@ module.exports = function svg() {
},
{
cleanupIDs: {
prefix: prefix + '-',
prefix: `${prefix}-`,
minify: true,
},
},
Expand All @@ -32,6 +34,15 @@ module.exports = function svg() {
)
.pipe(rename({ prefix: 'icon-' }))
.pipe(svgstore({ inlineSvg: true }))
.pipe(
cheerio({
// eslint-disable-next-line id-length
run: ($) => {
$('svg').attr('style', 'display:none');
},
parserOptions: { xmlMode: true },
})
)
.pipe(rename('sprite.svg'))
.pipe(gulp.dest(PATHS.build.svg));
};
10 changes: 5 additions & 5 deletions gulpfile.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
const gulp = require('gulp');

const styles = require('./gulp-tasks/styles');
const scss = require('./gulp-tasks/styles');
const tailwind = require('./gulp-tasks/tailwind');
const svg = require('./gulp-tasks/svg');
const zip = require('./gulp-tasks/zip');
const watch = require('./gulp-tasks/watch');
// const w3cValidator = require('./gulp-tasks/w3c-validator');

gulp.task('build', gulp.parallel(styles, tailwind, svg));
gulp.task('svg', svg);

gulp.task('production', gulp.series('build'));
gulp.task('styles', gulp.parallel(scss, tailwind));

gulp.task('zip', gulp.series('production', zip));
gulp.task('zip', zip);

// gulp.task('w3c-validator', w3cValidator);

gulp.task('default', gulp.parallel('build', watch));
gulp.task('default', gulp.parallel(svg, 'styles', watch));
11 changes: 7 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@
"version": "1.0.0",
"description": "",
"scripts": {
"start": "npm-run-all clean -p dev:*",
"start": "npm-run-all clean gulp:svg -p dev:*",
"gulp:svg": "gulp svg",
"gulp:styles": "gulp styles",
"dev:gulp": "gulp&",
"dev:eleventy": "node ./scripts/eleventy-dev.js",
"dev:webpack": "webpack --watch",
"build": "cross-env NODE_ENV=production npm-run-all clean build-webpack -p build:* && npm run beautify-html",
"build": "cross-env NODE_ENV=production npm-run-all -s clean gulp:svg build-webpack build-eleventy gulp:styles beautify-html",
"build:gulp": "gulp production",
"build:eleventy": "eleventy",
"build-eleventy": "eleventy",
"build-webpack": "webpack",
"clean": "rimraf dist/",
"zip": "cross-env NODE_ENV=production gulp zip",
"zip": "cross-env NODE_ENV=production npm run build && gulp zip",
"format": "pretty-quick --staged",
"lint:css": "stylelint --fix \"src/**/*.{scss,sass}\"",
"lint:js": "eslint --max-warnings 0 \"src/**/*.{jsx,js}\"",
Expand Down Expand Up @@ -54,6 +56,7 @@
"eslint-plugin-unicorn": "^28.0.2",
"fancy-log": "^1.3.3",
"gulp": "^4.0.2",
"gulp-cheerio": "^1.0.0",
"gulp-clean-css": "^4.3.0",
"gulp-dart-sass": "^1.0.2",
"gulp-if": "^3.0.0",
Expand Down
1 change: 1 addition & 0 deletions src/_layouts/base.njk
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
{% endblock stylesheets %}
</head>
<body>
{% svg_sprite %}

{% block content %}{% endblock content %}

Expand Down
10 changes: 5 additions & 5 deletions src/index.njk
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@
<h3 class="text-lg font-semibold mb-1">
An image inlined in the CSS example (compress such images manually!)
</h3>
<h4 class="max-w-xl text-lg text-red-600 mb-6 font-bold tracking-wide uppercase">
Attention! Please use this feature with caution as it may bloat the
final css file!
<h4 class="max-w-xl text-lg text-red-600 mb-6 font-bold tracking-wide">
<span class="uppercase">Attention!</span> Please use this feature with caution as it may bloat the
final CSS file. Inlining images could be a good approach if the file is quite small, in other cases prefer `&#123;% image %&#125;` tag.
</h4>
<div class="page-home__inline-image-example"></div>
</section>
Expand All @@ -70,7 +70,7 @@
Vector image example (using SVG sprite)
</h3>
<svg class="text-black fill-current w-20 h-20">
<use xlink:href="/svg/sprite.svg#icon-logo-example"></use>
<use xlink:href="#icon-logo-example"></use>
</svg>
</section>
<div class="flex items-center">
Expand All @@ -87,7 +87,7 @@
</h3>
<div class="flex">
<svg class="relative top-0.75 mr-2 w-5 h-5">
<use xlink:href="/svg/sprite.svg#icon-movies"></use>
<use xlink:href="#icon-movies"></use>
</svg>
<div class="text-sm">
<div class="line -mb-0.75">
Expand Down
16 changes: 0 additions & 16 deletions src/js/utils/svg-sprites.js

This file was deleted.

0 comments on commit 2130b10

Please sign in to comment.