{"id":14990333,"url":"https://github.com/jhildenbiddle/get-css-data","last_synced_at":"2025-04-09T16:07:55.840Z","repository":{"id":29241774,"uuid":"116582553","full_name":"jhildenbiddle/get-css-data","owner":"jhildenbiddle","description":"A micro-library for collecting stylesheet data from link and style nodes","archived":false,"fork":false,"pushed_at":"2024-02-07T02:45:27.000Z","size":1361,"stargazers_count":35,"open_issues_count":0,"forks_count":8,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-09T16:07:46.804Z","etag":null,"topics":["css","cssom","custom-properties","custom-property","es6","iframe","import","javascript","legacy","link","module","shadow","shadow-dom","style","stylesheet","web-component"],"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/jhildenbiddle.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":{"github":"jhildenbiddle"}},"created_at":"2018-01-07T16:52:19.000Z","updated_at":"2024-07-28T22:40:55.000Z","dependencies_parsed_at":"2024-06-18T15:26:59.173Z","dependency_job_id":"677971c8-f594-4888-964b-9069375b0363","html_url":"https://github.com/jhildenbiddle/get-css-data","commit_stats":null,"previous_names":[],"tags_count":29,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jhildenbiddle%2Fget-css-data","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jhildenbiddle%2Fget-css-data/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jhildenbiddle%2Fget-css-data/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jhildenbiddle%2Fget-css-data/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jhildenbiddle","download_url":"https://codeload.github.com/jhildenbiddle/get-css-data/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248065286,"owners_count":21041871,"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":["css","cssom","custom-properties","custom-property","es6","iframe","import","javascript","legacy","link","module","shadow","shadow-dom","style","stylesheet","web-component"],"created_at":"2024-09-24T14:19:54.408Z","updated_at":"2025-04-09T16:07:55.812Z","avatar_url":"https://github.com/jhildenbiddle.png","language":"JavaScript","readme":"# get-css-data\n\n[![NPM](https://img.shields.io/npm/v/get-css-data.svg?style=flat-square)](https://www.npmjs.com/package/get-css-data)\n[![GitHub Workflow Status (master)](https://img.shields.io/github/actions/workflow/status/jhildenbiddle/get-css-data/test.yml?branch=master\u0026label=checks\u0026style=flat-square)](https://github.com/jhildenbiddle/get-css-data/actions?query=branch%3Amaster+)\n[![Codacy code quality](https://img.shields.io/codacy/grade/ec8f2d2595804ab38ad138b762a640e6/master?style=flat-square)](https://app.codacy.com/gh/jhildenbiddle/get-css-data/dashboard?branch=master)\n[![Codacy branch coverage](https://img.shields.io/codacy/coverage/ec8f2d2595804ab38ad138b762a640e6/master?style=flat-square)](https://app.codacy.com/gh/jhildenbiddle/get-css-data/dashboard?branch=master)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://github.com/jhildenbiddle/get-css-data/blob/master/LICENSE)\n[![Sponsor this project](https://img.shields.io/static/v1?style=flat-square\u0026label=Sponsor\u0026message=%E2%9D%A4\u0026logo=GitHub\u0026color=%23fe8e86)](https://github.com/sponsors/jhildenbiddle)\n\nA micro-library for collecting stylesheet data from link and style nodes.\n\n## Features\n\n- Collects CSS data from `\u003clink\u003e` and `\u003cstyle\u003e` nodes\n- Collects static [Node.textContent](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent) or live [CSS Object Model (CSSOM)](https://developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model) data\n- Returns CSS data as a concatenated string and a DOM-ordered array of strings\n- Allows document, iframe, and [shadow DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM) traversal\n- Handles `@import` rules\n- Handles absolute and relative URLs\n- Inspect, modify and/or filter CSS data from each node\n- Modify XHR object before each request\n- UMD and ES6 modules available\n- Compatible with modern and legacy browsers (IE9+)\n- Lightweight (less than 1.5k min+gzip) and dependency-free\n\n## Installation\n\nNPM:\n\n```shell\nnpm install get-css-data --save\n```\n\n```javascript\n// file.js\nimport getCssData from 'get-css-data';\n\ngetCssData({\n  onComplete: function(cssText, cssArray, nodeArray) {\n    // Do stuff...\n  }\n});\n```\n\nGit:\n\n```bash\ngit clone https://github.com/jhildenbiddle/get-css-data.git\n```\n\nCDN ([jsdelivr.com](https://www.jsdelivr.com/) shown, also on [unpkg.com](https://unpkg.com/)):\n\n```html\n\u003c!-- ES5 (latest v2.x.x) --\u003e\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/get-css-data@2\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n  getCssData({\n    onComplete: function(cssText, cssArray, nodeArray) {\n      // Do stuff...\n    }\n  });\n\u003c/script\u003e\n```\n\n```html\n\u003c!-- ES6 module (latest v2.x.x) --\u003e\n\u003cscript type=\"module\"\u003e\n  import getCssData from 'https://cdn.jsdelivr.net/npm/get-css-data@2/dist/get-css-data.esm.min.js';\n\n  getCssData({\n    onComplete(cssText, cssArray, nodeArray) {\n      // Do stuff...\n    }\n  });\n\u003c/script\u003e\n```\n\n## Example\n\nHTML:\n\n```html\n\u003c!-- file.html --\u003e\n\u003chead\u003e\n  \u003clink rel=\"stylesheet\" href=\"style1.css\"\u003e\n  \u003cstyle\u003e\n    @import \"style2.css\";\n    p { color: blue; }\n  \u003c/style\u003e\n\u003c/head\u003e\n```\n\nCSS:\n\n```css\n/* style1.css */\np { color: red; }\n```\n\n```css\n/* style2.css */\np { color: green; }\n```\n\nJavaScript (see [Options](#options) for details)\n\n```javascript\ngetCssData({\n  onComplete: function(cssText, cssArray, nodeArray) {\n    console.log(cssText); // 1\n    console.log(cssArray); // 2\n    console.log(nodeArray); // 3\n  }\n});\n\n// 1 =\u003e 'p { color: red; } p { color: green; } p { color: blue; }'\n// 2 =\u003e ['p { color: red; }', 'p { color: green; } p { color: blue; }']\n// 3 =\u003e [\u003clinkElement\u003e, \u003cstyleElement\u003e]\n```\n\n## Options\n\n\u003c!-- no toc --\u003e\n- [rootElement](#optionsrootelement)\n- [include](#optionsinclude)\n- [exclude](#optionsexclude)\n- [filter](#optionsfilter)\n- [skipDisabled](#optionsskipdisabled)\n- [useCSSOM](#optionsusecssom)\n- [onBeforeSend](#optionsonbeforesend)\n- [onSuccess](#optionsonsuccess)\n- [onError](#optionsonerror)\n- [onComplete](#optionsoncomplete)\n\n**Example**\n\n```javascript\n// Default values shown\ngetCssData({\n  rootElement : document,\n  include     : 'link[rel=stylesheet],style',\n  exclude     : '',\n  filter      : '',\n  skipDisabled: true,\n  useCSSOM    : false,\n  onBeforeSend: function(xhr, node, url) {\n    // ...\n  },\n  onSuccess: function(cssText, node, url) {\n    // ...\n  },\n  onError: function(xhr, node, url) {\n    // ...\n  },\n  onComplete: function(cssText, cssArray, nodeArray) {\n    // ...\n  }\n});\n```\n\n### options.rootElement\n\n- Type: `object`\n- Default: `document`\n\nRoot element to traverse for `\u003clink\u003e` and `\u003cstyle\u003e` nodes.\n\n**Examples**\n\n```javascript\n// Document\ngetCssData({\n  rootElement: document // default\n});\n\n// Iframe (must be same domain with content loaded)\ngetCssData({\n  rootElement: (myIframe.contentDocument || myIframe.contentWindow.document)\n});\n\n// Shadow DOM\ngetCssData({\n  rootElement: myElement.shadowRoot\n});\n```\n\n### options.include\n\n- Type: `string`\n- Default: `\"link[rel=stylesheet],style\"`\n\nCSS selector matching `\u003clink\u003e` and `\u003cstyle\u003e` nodes to collect data from. The default value includes all style and link nodes.\n\n**Example**\n\n```javascript\ngetCssData({\n  // Include only \u003clink rel=\"stylesheet\"\u003e nodes\n  // with an href that does not contains \"bootstrap\"\n  include: 'link[rel=stylesheet]:not([href*=bootstrap])',\n});\n```\n\n### options.exclude\n\n- Type: `string`\n\nCSS selector matching `\u003clink\u003e` and `\u003cstyle\u003e` nodes to exclude from those matched by [options.include](#optionsinclude).\n\n**Example**\n\n```javascript\ngetCssData({\n  // Of matched `include` nodes, exclude any node\n  // with an href that contains \"bootstrap\"\n  exclude: '[href*=bootstrap]',\n});\n```\n\n### options.filter\n\n- Type: `object`\n\nRegular expression used to filter node CSS data. Each block of CSS data is tested against the filter, and only matching data is processed.\n\n**Example**\n\n```javascript\ngetCssData({\n  // Test each block of CSS for the existence\n  // of \".myclass\". If found, process the CSS.\n  // If not, ignore the CSS.\n  filter: /\\.myclass/,\n});\n```\n\n### options.skipDisabled\n\n- Type: `boolean`\n- Default: `true`\n\nDetermines if disabled stylesheets will be skipped while collecting CSS data.\n\n**Example**\n\n```javascript\ngetCssData({\n  skipDisabled: true // default\n});\n```\n\n### options.useCSSOM\n\n- Type: `boolean`\n- Default: `false`\n\nDetermines how CSS data will be collected from `\u003cstyle\u003e` nodes.\n\nWhen `false`, static CSS data is collected by reading each node's [textContent](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent) value. This method is fast, but the data collected will not reflect changes made using the [`deleteRule()`](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/deleteRule) or [`insertRule()`](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/insertRule) methods. When `true`, live CSS data is collected by iterating over each node's [`CSSRuleList`](https://developer.mozilla.org/en-US/docs/Web/API/CSSRuleList) and concatenating all [`CSSRule.cssText`](https://developer.mozilla.org/en-US/docs/Web/API/CSSRule/cssText) values into a single string. This method is slower, but the data collected accurately reflects all changes made to the stylesheet.\n\nKeep in mind that browsers often drop unrecognized selectors, properties, and values when parsing static CSS. For example, Chrome/Safari will drop declarations with Mozilla's `-moz-` prefix, while Firefox will drop declarations with Chrome/Safari's `-webkit` prefix . This means that data collected when this options is set to `true` will likely vary between browsers and differ from the static CSS collected when it is set to `false`.\n\n**Example**\n\n```javascript\ngetCssData({\n  useCSSOM: false // default\n});\n```\n\n### options.onBeforeSend\n\n- Type: `function`\n- Arguments:\n  1. **xhr**: The XHR `object` containing details of the request\n  2. **node**: The source node `object` reference\n  3. **url**: The source URL `string` (`\u003clink\u003e` href or `@import` url)\n\nCallback before each [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) (XHR) is sent. Allows modifying the XML object by setting properties, calling methods, or adding event handlers.\n\n**Example**\n\n```javascript\ngetCssData({\n  onBeforeSend: function(xhr, node, url) {\n    // Domain-specific XHR settings\n    if (/some-domain.com/.test(url)) {\n      xhr.withCredentials = true;\n      xhr.setRequestHeader(\"foo\", \"1\");\n      xhr.setRequestHeader(\"bar\", \"2\");\n    }\n  }\n});\n```\n\n### options.onSuccess\n\n- Type: `function`\n- Arguments:\n  1. **cssText**: A `string` of CSS text from `node` and `url`\n  1. **node**: The source node `object` reference\n  1. **url**: The source URL `string` (`\u003clink\u003e` href, `@import` url, or page url for `\u003cstyle\u003e` data)\n\nCallback after CSS data has been collected from each node. Allows modifying the CSS data before it is added to the final output by returning any `string` value or skipping the CSS data by returning `false` or an empty string (`\"\"`).\n\nNote that the order in which `\u003clink\u003e` and `@import` CSS data is \"successfully\" collected (thereby triggering this callback) is not guaranteed as these requests are asynchronous. To access CSS data in DOM order, use the `cssArray` argument passed to the [options.oncomplete](#optionsoncomplete) callback.\n\n**Example**\n\n```javascript\ngetCssData({\n  onSuccess: function(cssText, node, url) {\n    // Replace all instances of \"color: red\" with \"color: blue\"\n    const newCssText = cssText.replace(/color:\\s*red\\s;/g, 'color: blue;');\n\n    return newCssText;\n  }\n});\n```\n\n### options.onError\n\n- Type: `function`\n- Arguments:\n  1. **xhr**: The XHR `object` containing details of the request\n  2. **node**: The source node `object` reference\n  3. **url**: The source URL `string` (`\u003clink\u003e` href or `@import` url)\n\nCallback after `\u003clink\u003e` or `@import` request has failed or when\n`xhr.responseText` appears to be HTML instead of CSS.\n\n**Example**\n\n```javascript\ngetCssData({\n  onError: function(xhr, node, url) {\n    console.log(xhr.status); // 1\n    console.log(xhr.statusText); // 2\n  }\n});\n\n// 1 =\u003e '404'\n// 2 =\u003e 'Not Found'\n```\n\n### options.onComplete\n\n- Type: `function`\n- Arguments:\n  1. **cssText**: A `string` of concatenated CSS text from all nodes in DOM order.\n  1. **cssArray**: An `array` of per-node CSS text in DOM order. The node containing each CSS text block is available at the same **nodeArray** index.\n  1. **nodeArray**: An `array` of processed `\u003cstyle\u003e` and `\u003clink\u003e` nodes in DOM order. The CSS text for each node is available at the same **cssArray** index.\n\nCallback after CSS data has been collected from all nodes.\n\n**Example**\n\n```javascript\ngetCssData({\n  onComplete: function(cssText, cssArray, nodeArray) {\n    // ...\n  }\n});\n```\n\n## Sponsorship\n\nA [sponsorship](https://github.com/sponsors/jhildenbiddle) is more than just a way to show appreciation for the open-source authors and projects we rely on; it can be the spark that ignites the next big idea, the inspiration to create something new, and the motivation to share so that others may benefit.\n\nIf you benefit from this project, please consider lending your support and encouraging future efforts by [becoming a sponsor](https://github.com/sponsors/jhildenbiddle).\n\nThank you! 🙏🏻\n\n## Contact \u0026 Support\n\n- Follow 👨🏻‍💻 **@jhildenbiddle** on [Twitter](https://twitter.com/jhildenbiddle) and [GitHub](https://github.com/jhildenbiddle) for announcements\n- Create a 💬 [GitHub issue](https://github.com/jhildenbiddle/get-css-data/issues) for bug reports, feature requests, or questions\n- Add a ⭐️ [star on GitHub](https://github.com/jhildenbiddle/get-css-data) and 🐦 [tweet](https://twitter.com/intent/tweet?url=https%3A%2F%2Fgithub.com%2Fjhildenbiddle%2Fget-css-data\u0026hashtags=css,developers,frontend,javascript) to promote the project\n- Become a 💖 [sponsor](https://github.com/sponsors/jhildenbiddle) to support the project and future efforts\n\n## License\n\nThis project is licensed under the MIT License. See the [LICENSE](https://github.com/jhildenbiddle/get-css-data/blob/master/LICENSE) for details.\n\nCopyright (c) John Hildenbiddle ([@jhildenbiddle](https://twitter.com/jhildenbiddle))\n","funding_links":["https://github.com/sponsors/jhildenbiddle"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjhildenbiddle%2Fget-css-data","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjhildenbiddle%2Fget-css-data","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjhildenbiddle%2Fget-css-data/lists"}