{"id":13397879,"url":"https://github.com/ai/webp-in-css","last_synced_at":"2025-05-16T14:06:56.161Z","repository":{"id":34296340,"uuid":"175278315","full_name":"ai/webp-in-css","owner":"ai","description":"PostCSS plugin and tiny JS script (131 bytes) to use WebP in CSS background","archived":false,"fork":false,"pushed_at":"2024-09-22T12:27:53.000Z","size":1086,"stargazers_count":346,"open_issues_count":5,"forks_count":26,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-05-07T04:46:22.939Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ai.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"open_collective":"postcss"}},"created_at":"2019-03-12T18:57:35.000Z","updated_at":"2025-02-18T12:50:36.000Z","dependencies_parsed_at":"2024-11-21T06:01:34.753Z","dependency_job_id":"ebfb0592-75dd-40df-a20f-922de2f1ebf1","html_url":"https://github.com/ai/webp-in-css","commit_stats":{"total_commits":124,"total_committers":14,"mean_commits":8.857142857142858,"dds":"0.25806451612903225","last_synced_commit":"5a22b352c68e5d2d4292a14767f8ea7c1fa69d4c"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ai%2Fwebp-in-css","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ai%2Fwebp-in-css/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ai%2Fwebp-in-css/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ai%2Fwebp-in-css/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ai","download_url":"https://codeload.github.com/ai/webp-in-css/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254544146,"owners_count":22088807,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-30T18:01:50.745Z","updated_at":"2025-05-16T14:06:56.140Z","avatar_url":"https://github.com/ai.png","language":"JavaScript","funding_links":["https://opencollective.com/postcss"],"categories":["JavaScript"],"sub_categories":[],"readme":"# WebP in CSS\n\n\u003cimg src=\"https://ai.github.io/webp-in-css/webp-logo.svg\" align=\"right\"\n     alt=\"WebP logo\" width=\"150\" height=\"180\"\u003e\n\n[PostCSS] plugin and tiny JS script (175 bytes) to use [WebP] in CSS `background`.\n\nThis tool will make your images [25% smaller] for Chrome, Firefox, and Edge.\nSafari will download the bigger JPEG/PNG image.\n\nYou add `require('webp-in-css/polyfill')` to your JS bundle and write CSS like:\n\n```css\n.logo {\n  width: 30px;\n  height: 30px;\n  background: url(/logo.png);\n}\n```\n\nThe script will set `webp` or `no-webp` class on `\u003cbody\u003e`\nand PostCSS plugin will generate:\n\n```css\n.logo {\n  width: 30px;\n  height: 30px;\n  background: url(/logo.webp) no-repeat;\n}\nbody.webp .logo {\n  background-image: url(/logo.webp);\n}\nbody.no-webp .logo, body.no-js .logo {\n  background-image: url(/logo.png);\n}\n```\n\nIf you want to use `addNoJs` option, you need manually set `no-js` class on `\u003cbody\u003e`.\nPolyfill will remove this class, if JS is enabled in the browser. Polyfill should\nbe inserted in the `\u003chead\u003e`, without `async` or `defer` attributes, before css.\n`addNoJs` option is enabled by default.\n\n[25% smaller]: https://developers.google.com/speed/webp/docs/webp_lossless_alpha_study#results\n[PostCSS]: https://github.com/postcss/postcss\n[WebP]: https://en.wikipedia.org/wiki/WebP\n\n\u003ca href=\"https://evilmartians.com/?utm_source=webp-in-css\"\u003e\n  \u003cimg src=\"https://evilmartians.com/badges/sponsored-by-evil-martians.svg\"\n       alt=\"Sponsored by Evil Martians\" width=\"236\" height=\"54\"\u003e\n\u003c/a\u003e\n\n\n## Usage\n\n**Step 1:** Install tool:\n\n```sh\nnpm install --save-dev postcss webp-in-css\n```\n\n**Step 2:** convert all your JPEG/PNG images to WebP by [Squoosh].\nSet checkbox on `Lossless` for PNG images and remove it for JPEG.\n\nWe recommend `Reduce palette` for most of the PNG images.\n\nSave WebP images in the same places of JPEG/PNG images:\n`img/bg.png` → `img/bg.webp`.\n\n**Step 3:** use `\u003cpicture\u003e` to insert WebP images in HTML:\n\n```diff html\n- \u003cimg src=\"/screenshot.jpg\" alt=\"Screenshot\"\u003e\n+ \u003cpicture\u003e\n+   \u003csource srcset=\"/screenshot.webp\" type=\"image/webp\"\u003e\n+   \u003cimg src=\"/screenshot.jpg\" alt=\"Screenshot\"\u003e\n+ \u003c/picture\u003e\n```\n\n**Step 4:** add JS script to your client-side JS bundle:\n\n```diff js\n+ import 'webp-in-css/polyfill'\n```\n\nSince JS script is very small (142 bytes), the best way for landings\nis to inline it to HTML:\n\n```diff html\n  \u003c/head\u003e\n  \u003cbody\u003e\n+   \u003cscript\u003e\u003c%= readFile('node_modules/webp-in-css/polyfill.js') %\u003e\u003c/script\u003e\n```\n\nNote, that you need to put `\u003cscript\u003e` inside `\u003cbody\u003e`, not `\u003chead\u003e`.\n\n**Step 5:** check do you use PostCSS already in your bundler.\nYou can check `postcss.config.js` in the project root,\n`\"postcss\"` section in `package.json` or `postcss` in bundle config.\n\nIf you don’t have it already, add PostCSS to your bundle:\n\n* For webpack see [postcss-loader] docs.\n* For Parcel create `postcss.config.js` file.\n  It already has PostCSS support.\n* For Gulp check [gulp-postcss] docs.\n\n**Step 6:** Add `webp-in-css/plugin` to PostCSS plugins:\n\n```diff js\nmodule.exports = {\n  plugins: [\n+   require('webp-in-css/plugin'),\n    require('autoprefixer')\n  ]\n}\n```\n\nIf you use CSS Modules in webpack add `modules: true` option:\n\n```diff js\nmodule.exports = {\n  plugins: [\n-   require('webp-in-css/plugin'),\n+   require('webp-in-css/plugin')({ modules: true }),\n    require('autoprefixer')\n  ]\n}\n```\n\nWe also recommend to put all images from CSS to preload content:\n\n```diff html\n+   \u003clink rel=\"preload\" as=\"image\" type=\"image/webp\" href=\"/logo.webp\"\u003e\n    \u003cscript\u003e\u003c%= readFile('node_modules/webp-in-css/polyfill.js') %\u003e\u003c/script\u003e\n  \u003c/head\u003e\n```\n\n[postcss-loader]: https://github.com/postcss/postcss-loader#usage\n[gulp-postcss]: https://github.com/postcss/gulp-postcss\n[Squoosh]: https://squoosh.app/\n\n\n## PostCSS Options\n\n```js\nmodule.exports = {\n  plugins: [\n    require('webp-in-css/plugin')({ /* options */ }),\n  ]\n}\n```\n\n* `modules` boolean: wrap classes to `:global()` to support CSS Modules.\n  `false` by default.\n* `webpClass` string: class name for browser with WebP support.\n* `noWebpClass` string: class name for browser without WebP support.\n* `addNoJs` boolean: add `no-js` class to selector.\n  `true` by default.\n* `noJsClass` string: class name for browser without JS support.\n* `check` function: should return boolean if we need to change declaration,\n  default:\n\n  ```js\n  decl =\u003e /\\.(jpe?g|png)(?!(\\.webp|.*[\u0026?]format=webp))/i.test(decl.value)\n  ```\n* `rename` function: get a new file name from old name,\n  like `(oldName: string) =\u003e string`,\n  then `url(./image.png)` → `url(./image.png.webp)`.\n  Often you will need to change `check` option too.\n  \n  ```js\n  check: decl =\u003e /\\.jpg/.test(decl.value) \u0026\u0026 !decl.value.includes(\"as=webp\"),\n  rename: url =\u003e url.replace(\".jpg\", \".jpg?as=webp\")\n  ```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fai%2Fwebp-in-css","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fai%2Fwebp-in-css","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fai%2Fwebp-in-css/lists"}