├── .eleventyignore ├── .github └── ISSUE_TEMPLATE │ ├── config.yml │ ├── demo.yaml │ ├── general.yaml │ ├── spec.yaml │ ├── topic.yaml │ └── use_case.yaml ├── .gitignore ├── .nvmrc ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── LICENSE.md ├── README.md ├── docs ├── _data │ ├── footer.json │ └── site.cjs ├── _includes │ ├── _joiningBlocks │ │ ├── footer │ │ │ └── 10-menu.njk │ │ └── head │ │ │ └── 20-icons.njk │ ├── base.njk │ ├── layout-about.njk │ ├── layout-articles.njk │ ├── layout-home.njk │ └── sections │ │ ├── drawer-about.njk │ │ ├── drawer-articles.njk │ │ ├── drawer-home.njk │ │ ├── footer.njk │ │ ├── head.njk │ │ ├── header.njk │ │ └── scripts.njk ├── about │ ├── index.md │ ├── introduction.md │ ├── libraries.md │ ├── resources.md │ └── specifications.md ├── articles │ ├── index.md │ ├── main │ │ ├── getting-started.md │ │ └── index.md │ └── using │ │ ├── index.md │ │ └── styling-shadow.md ├── assets │ ├── icons │ │ ├── icon-128x128.png │ │ ├── icon-144x144.png │ │ ├── icon-152x152.png │ │ ├── icon-16x16.png │ │ ├── icon-192x192.png │ │ ├── icon-32x32.png │ │ ├── icon-384x384.png │ │ ├── icon-512x512.png │ │ ├── icon-72x72.png │ │ └── icon-96x96.png │ ├── logo.svg │ ├── style.css │ └── webmanifest.json ├── index.md ├── light-dark.css ├── markdown.css ├── site.css ├── styles.css └── theme.css ├── eleventy.config.js ├── package-lock.json ├── package.json └── plan ├── README.md └── outline.md /.eleventyignore: -------------------------------------------------------------------------------- 1 | node_modules/** 2 | /docs/_assets 3 | /docs/_includes 4 | /docs/_data 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Questions or discussion? 4 | url: https://join.slack.com/t/webcomponentcommunity/shared_invite/zt-uinb2qud-cDvio5cC7IllxZfcTFf4QQ 5 | about: Please post general questions or discussion topics here. 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/demo.yaml: -------------------------------------------------------------------------------- 1 | name: Request for demo content 2 | description: Request to add demo content 3 | title: '[demo] ' 4 | labels: [demo, documentation] 5 | body: 6 | - type: checkboxes 7 | id: terms 8 | attributes: 9 | label: Code of conduct 10 | description: By submitting this issue, you agree to follow our [code of conduct](https://www.w3.org/Consortium/cepc/). 11 | options: 12 | - label: I agree to follow this project's code of conduct. 13 | required: true 14 | - type: textarea 15 | id: details 16 | attributes: 17 | label: Description of request 18 | description: Please tell us about the content you would like to see added to this project. You can attach images or files by clicking this area to highlight it and then dragging files in. 19 | - type: input 20 | id: link 21 | attributes: 22 | label: Related link(s) 23 | - type: checkboxes 24 | id: author 25 | attributes: 26 | label: Are you interested in authoring this content? 27 | options: 28 | - label: "Yes" 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/general.yaml: -------------------------------------------------------------------------------- 1 | name: General request 2 | labels: ['question'] 3 | body: 4 | - type: checkboxes 5 | id: terms 6 | attributes: 7 | label: Code of conduct 8 | description: By submitting this issue, you agree to follow our [code of conduct](https://www.w3.org/Consortium/cepc/). 9 | options: 10 | - label: I agree to follow this project's code of conduct. 11 | required: true 12 | - type: textarea 13 | id: details 14 | attributes: 15 | label: Description of request 16 | description: You can attach images or files by clicking this area to highlight it and then dragging files in. 17 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/spec.yaml: -------------------------------------------------------------------------------- 1 | name: Specification request for inclusion 2 | description: Request to add specification content 3 | labels: [spec, documentation] 4 | title: '[spec] ' 5 | body: 6 | - type: checkboxes 7 | id: terms 8 | attributes: 9 | label: Code of conduct 10 | description: By submitting this issue, you agree to follow our [code of conduct](https://www.w3.org/Consortium/cepc/). 11 | options: 12 | - label: I agree to follow this project's code of conduct. 13 | required: true 14 | - type: textarea 15 | id: details 16 | attributes: 17 | label: Description of request 18 | description: Please tell us about the content you would like to see added to this project. You can attach images or files by clicking this area to highlight it and then dragging files in. 19 | - type: input 20 | id: link 21 | attributes: 22 | label: Related link(s) 23 | - type: checkboxes 24 | id: author 25 | attributes: 26 | label: Are you interested in authoring this content? 27 | options: 28 | - label: "Yes" 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/topic.yaml: -------------------------------------------------------------------------------- 1 | name: Topic content request 2 | description: Request to add topic content 3 | labels: [topic, documentation] 4 | title: '[topic] ' 5 | body: 6 | - type: checkboxes 7 | id: terms 8 | attributes: 9 | label: Code of conduct 10 | description: By submitting this issue, you agree to follow our [code of conduct](https://www.w3.org/Consortium/cepc/). 11 | options: 12 | - label: I agree to follow this project's code of conduct. 13 | required: true 14 | - type: textarea 15 | id: details 16 | attributes: 17 | label: Description of request 18 | description: Please tell us about the content you would like to see added to this project. You can attach images or files by clicking this area to highlight it and then dragging files in. 19 | - type: input 20 | id: link 21 | attributes: 22 | label: Related link(s) 23 | - type: checkboxes 24 | id: author 25 | attributes: 26 | label: Are you interested in authoring this content? 27 | options: 28 | - label: "Yes" 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/use_case.yaml: -------------------------------------------------------------------------------- 1 | name: Use-case content request 2 | description: Request to add use-case content 3 | labels: ["use case", documentation] 4 | title: '[use case] ' 5 | body: 6 | - type: checkboxes 7 | id: terms 8 | attributes: 9 | label: Code of conduct 10 | description: By submitting this issue, you agree to follow our [code of conduct](https://www.w3.org/Consortium/cepc/). 11 | options: 12 | - label: I agree to follow this project's code of conduct. 13 | required: true 14 | - type: textarea 15 | id: details 16 | attributes: 17 | label: Description of request 18 | description: Please tell us about the content you would like to see added to this project. You can attach images or files by clicking this area to highlight it and then dragging files in. 19 | - type: input 20 | id: link 21 | attributes: 22 | label: Related link(s) 23 | - type: checkboxes 24 | id: author 25 | attributes: 26 | label: Are you interested in authoring this content? 27 | options: 28 | - label: "Yes" 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## editors 2 | /.idea 3 | /.vscode 4 | 5 | ## system files 6 | .DS_Store 7 | 8 | 9 | ## npm 10 | node_modules 11 | npm-debug.log 12 | yarn-error.log 13 | 14 | ## temp folders 15 | /.tmp/ 16 | 17 | ## build output 18 | dist 19 | dist-types 20 | stats.html 21 | *.tsbuildinfo 22 | 23 | ## Rocket ignore files (need to be the full relative path to the folders) 24 | docs/_merged_data/ 25 | docs/_merged_assets/ 26 | docs/_merged_includes/ 27 | _site 28 | _site-dev 29 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v20 2 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | The [Web Components Community Group](https://www.w3.org/community/webcomponents/) documentation repository, being work of the [World Wide Web Consortium (W3C)](https://www.w3.org/), is subject to the [W3C Code of Ethics and Professional Conduct](https://www.w3.org/Consortium/cepc/). 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributor Guidelines 2 | 3 | Thank you for your interest in contributing to the [Web Components Community Group](https://www.w3.org/community/webcomponents/)! 4 | 5 | Contributions to this repository are intended to become part of documents governed by the: 6 | 7 | * [W3C Patent Policy](https://www.w3.org/Consortium/Patent-Policy-20200915/) 8 | * [Software and Document License](https://www.w3.org/Consortium/Legal/copyright-software) 9 | 10 | To make substantive contributions to specifications, you must either participate 11 | in the relevant W3C Working Group or make a non-member patent licensing commitment. 12 | 13 | ## Issue disclosure and discussion 14 | 15 | The first step for any substantive contribution is to either: 16 | 17 | 1. [Find an existing issue](https://github.com/w3c/csswg-drafts/issues) directly related to the contribution 18 | 2. [Add a new issue](https://github.com/w3c/csswg-drafts/issues/new) 19 | 20 | Issues are where individual reports and Community Group discussions come together such 21 | that the eventual consensus can be turned into official language. 22 | 23 | ## Goals and Non-Goals 24 | 25 | The main goal of the Web Components Community Group docs-and-guides effort is to provide explanation, advocacy, and documentation of shared web components concepts in a common location that is not tied to any specific web components library. 26 | 27 | This documentation should be ideal for readers interested in learning about web components first - before thinking about libraries; and for web component libraries to reference to cover the standard web components foundations without writing it all themselves. 28 | 29 | ### Goals 30 | * Provide a polished landing page for web components, similar in spirit to homepages for frameworks. 31 | * Explain what web components are and why they are useful 32 | * Advocate for web components in a library-neutral way 33 | * Document core web component technical concepts 34 | * Educate readers on useful library-agnostic patterns and best practices 35 | * Orient readers to the broader web components ecosystem, including standards work, resources, communities, libraries, tools, and components. 36 | 37 | ### Non-Goals 38 | * Duplicate MDN references of the web components APIs 39 | * Document or advocate specific web components libraries 40 | 41 | ## Normative and/or substantive contributions 42 | 43 | The Web Components Community Group operates via the consensus of its membership, and discusses all significant matters prior to implementation. 44 | 45 | Aside from managing issues and PRs on GitHub, the Community Group discusses recommendations, goals, and planning via events available on [this shared calendar](https://calendar.google.com/calendar/u/0/embed?src=o25bim5rvcu42mfnqilirpmp44@group.calendar.google.com). 46 | 47 | ### Contribution 48 | 49 | Please follow the [Pull Request template](https://github.com/w3c/csswg-drafts/blob/master/.github/PULL_REQUEST_TEMPLATE.md) when contributing to the repository. 50 | 51 | ## Non-substantive contributions 52 | 53 | For simple spelling, grammar, or markup fixes unrelated to the substance of a 54 | specification, issuing a pull request without a corresponding issue is acceptable. 55 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | All documents in this Repository are licensed by contributors 2 | under the 3 | [W3C Software and Document License](https://www.w3.org/Consortium/Legal/copyright-software). 4 | 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # All about web components 2 | 3 | This repository brought to you by the [Web Components Community Group](https://www.w3.org/community/webcomponents/); the goal being to collect and share documentation and guides for web component best practices. 4 | -------------------------------------------------------------------------------- /docs/_data/footer.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "Discover", 4 | "children": [ 5 | { 6 | "text": "Help and Feedback", 7 | "href": "https://github.com/webcomponents-cg/docs-and-guides/issues" 8 | } 9 | ] 10 | }, 11 | { 12 | "name": "Follow", 13 | "children": [ 14 | { 15 | "text": "GitHub", 16 | "href": "https://github.com/webcomponents-cg/docs-and-guides" 17 | } 18 | ] 19 | }, 20 | { 21 | "name": "Support", 22 | "children": [ 23 | { 24 | "text": "Contribute", 25 | "href": "https://github.com/webcomponents-cg/docs-and-guides/blob/main/CONTRIBUTING.md" 26 | } 27 | ] 28 | } 29 | ] 30 | -------------------------------------------------------------------------------- /docs/_data/site.cjs: -------------------------------------------------------------------------------- 1 | module.exports = function () { 2 | return { 3 | dir: 'ltr', 4 | lang: 'en', 5 | name: 'Web Components Community Group at W3C', 6 | description: 'Collect and share documentation and guides for web component best practices', 7 | socialLinks: [ 8 | { 9 | name: 'GitHub', 10 | url: 'https://github.com/webcomponents-cg/docs-and-guides', 11 | }, 12 | ], 13 | gitSiteUrl: 'https://github.com/webcomponents-cg/docs-and-guides', 14 | gitBranch: 'master', 15 | helpUrl: 'https://github.com/webcomponents-cg/docs-and-guides/issues', 16 | logoAlt: 'Web Components Community Group Logo', 17 | iconColorMaskIcon: '#3f93ce', 18 | iconColorMsapplicationTileColor: '#1d3557', 19 | iconColorThemeColor: '#1d3557', 20 | }; 21 | }; 22 | -------------------------------------------------------------------------------- /docs/_includes/_joiningBlocks/footer/10-menu.njk: -------------------------------------------------------------------------------- 1 | 40 | -------------------------------------------------------------------------------- /docs/_includes/_joiningBlocks/head/20-icons.njk: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /docs/_includes/base.njk: -------------------------------------------------------------------------------- 1 | 2 | 3 | {% include "sections/head.njk" %} 4 | 5 | {% include "sections/header.njk" %} 6 | 7 | {{ content | safe }} 8 | 9 | {% include "sections/footer.njk" %} 10 | {% include "sections/scripts.njk" %} 11 | 12 | -------------------------------------------------------------------------------- /docs/_includes/layout-about.njk: -------------------------------------------------------------------------------- 1 | --- 2 | layout: base.njk 3 | layoutType: index 4 | --- 5 | 6 |
7 |
8 | {% include "sections/drawer-about.njk" %} 9 |
10 | {{ content | safe }} 11 |
12 |
13 |
-------------------------------------------------------------------------------- /docs/_includes/layout-articles.njk: -------------------------------------------------------------------------------- 1 | --- 2 | layout: base.njk 3 | layoutType: index 4 | --- 5 | 6 |
7 |
8 | {% include "sections/drawer-articles.njk" %} 9 |
10 | {{ content | safe }} 11 |
12 |
13 |
-------------------------------------------------------------------------------- /docs/_includes/layout-home.njk: -------------------------------------------------------------------------------- 1 | --- 2 | layout: base.njk 3 | layoutType: home 4 | --- 5 | 6 |
7 |
8 | {% include "sections/drawer-home.njk" %} 9 |
10 | 11 |

Web Components CG

12 |

We care about web components.

13 |
14 | Read Articles 15 |
16 |

Why a Community Group?

17 |
18 |
19 |

Connect

20 | This group is for collaboration between people working on web components libraries, tools, documentation and standards. 21 |
22 |
23 |

Collaborate

24 | Areas we expect to work on include gap analysis, design principles, common protocols, discoverability and quality, documentation, tooling, and more. 25 |
26 |
27 |

Common Problems

28 | We will work together on projects of shared interest in order to enhance interoperability, solve common problems, build shared community resources, and ultimately continue to grow a cooperative, productive, and happy web components ecosystem. 29 |
30 |
31 | {{ content | safe }} 32 |
33 |
34 |
-------------------------------------------------------------------------------- /docs/_includes/sections/drawer-about.njk: -------------------------------------------------------------------------------- 1 | 2 | 3 | 30 | -------------------------------------------------------------------------------- /docs/_includes/sections/drawer-articles.njk: -------------------------------------------------------------------------------- 1 | 2 | 3 | 34 | -------------------------------------------------------------------------------- /docs/_includes/sections/drawer-home.njk: -------------------------------------------------------------------------------- 1 | 2 | 3 | 24 | -------------------------------------------------------------------------------- /docs/_includes/sections/footer.njk: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/_includes/sections/head.njk: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Web Components CG: Web Components Community Group at W3C 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 27 | 28 | -------------------------------------------------------------------------------- /docs/_includes/sections/header.njk: -------------------------------------------------------------------------------- 1 |
2 |
3 | 9 | 10 | Web Components Community Group Logo 11 | Web Components Community Group at W3C 12 | 13 | About 14 | Articles 15 | Toggle darkmode 16 | 23 |
24 |
-------------------------------------------------------------------------------- /docs/_includes/sections/scripts.njk: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/about/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layout-about.njk 3 | --- 4 | 5 | # About 6 | 7 | Web components! -------------------------------------------------------------------------------- /docs/about/introduction.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layout-about.njk 3 | --- 4 | 5 | # Introduction 6 | 7 | ## What are web components? 8 | Web components are a set of web platform APIs that allow you to create new custom, reusable, encapsulated HTML tags to use in web pages and web apps. Custom components and widgets build on the Web Component standards, will work across modern browsers, and can be used with any JavaScript library or framework that works with HTML. 9 | 10 | Web components are based on existing web standards. Features to support web components are currently being added to the HTML and DOM specs, letting web developers easily extend HTML with new elements with encapsulated styling and custom behavior. 11 | 12 | ## Specifications 13 | Web components are based on four main specifications: 14 | 15 | ### Custom Elements 16 | The Custom Elements specification lays the foundation for designing and using new types of DOM elements. 17 | 18 | ### Shadow DOM 19 | The shadow DOM specification defines how to use encapsulated style and markup in web components. 20 | 21 | ### ES Modules 22 | The ES Modules specification defines the inclusion and reuse of JS documents in a standards based, modular, performant way. 23 | 24 | ### HTML Template 25 | The HTML template element specification defines how to declare fragments of markup that go unused at page load, but can be instantiated later on at runtime. 26 | 27 | ## How do I use a web component? 28 | The components on this site provide new HTML elements that you can use in your web pages and web applications. 29 | 30 | Using a custom element is as simple as importing it, and using the new tags in an HTML document. For example, to use the paper-button element: 31 | 32 | ```html 33 | 34 | ... 35 | raised 36 | ``` 37 | 38 | There are a number of ways to install custom elements. When you find an element you want to use, look at its README for the commands to install it. Most elements today can be installed with NPM. NPM also handles installing the components' dependencies. For more information on NPM, see npmjs.com. 39 | 40 | For example, the paper-button overview describes the install process with npm: 41 | 42 | ```bash 43 | mkdir my-new-app && cd my-new-app 44 | npm install --save @polymer/paper-button 45 | ``` 46 | 47 | ## How do I define a new HTML element? 48 | This section describes the syntax for the cross-browser version of the Web Components specification. 49 | 50 | Use JavaScript to define a new HTML element and its tag with the customElements global. Call customElements.define() with the tag name you want to create and a JavaScript class that extends the base HTMLElement. 51 | 52 | For example, to define a mobile drawer panel, : 53 | 54 | ```js 55 | class AppDrawer extends HTMLElement {...} 56 | window.customElements.define('app-drawer', AppDrawer); 57 | ``` 58 | 59 | To use the new tag: 60 | 61 | ```html 62 | 63 | ``` 64 | 65 | Using a custom element is no different to using a
or any other element. Instances can be declared on the page, created dynamically in JavaScript, event listeners can be attached, etc. 66 | 67 | ```html 68 | 76 | ``` 77 | 78 | ## Creating and using a shadow root 79 | This section describes the syntax for creating shadow DOM with the new cross-browser version (v1) of the shadow DOM specification. Shadow DOM is a new DOM feature that helps you build components. You can think of shadow DOM as a scoped subtree inside your element. 80 | 81 | A shadow root is a document fragment that gets attached to a "host" element. The act of attaching a shadow root is how the element gains its shadow DOM. To create shadow DOM for an element, call element.attachShadow(): 82 | 83 | ```js 84 | const header = document.createElement('header'); 85 | const shadowRoot = header.attachShadow({mode: 'open'}); 86 | shadowRoot.innerHTML = '

Hello Shadow DOM

'; // Could also use appendChild(). 87 | // header.shadowRoot === shadowRoot 88 | // shadowRoot.host === header 89 | ``` 90 | 91 | ## Libraries for building web components 92 | Many libraries already exist that make it easier to build web components. The libraries section of the site has additional details but here are some you can try out: 93 | 94 | - Hybrids is a UI library for creating Web Components with simple and functional API. 95 | - LitElement uses lit-html to render into the element's Shadow DOM and adds API to help manage element properties and attributes. 96 | - Polymer provides a set of features for creating custom elements. 97 | - Slim.js is an opensource lightweight web component library that provides data-binding and extended capabilities for components, using es6 native class inheritance. 98 | - Stencil is an opensource compiler that generates standards-compliant web components. 99 | -------------------------------------------------------------------------------- /docs/about/libraries.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layout-about.njk 3 | --- 4 | 5 | # Libraries 6 | 7 | ## Why use a web component library? 8 | Web Components can be hard to write from scratch. There’s a lot to think about, and writing a component can require a lot of boilerplate code. Fortunately, there are some great libraries that can make creating custom elements more straightforward, and save you a lot of time and effort. 9 | 10 | It’s important to note that you don’t need to use a library to build and share a custom element! Raw custom elements are great if your task is limited to one or a few elements, allowing a more streamlined implementation and preventing library lock-in. 11 | 12 | However, if you’re writing lots and lots of custom elements, using a library can make your code simpler and cleaner, and your workflow more efficient. 13 | 14 | ## What should you look for in a web component library? 15 | When choosing a web component library, make sure it has a large enough featureset to cover all of your use cases. Interoperability is also important - does the library leak implementation details? A good web component library should produce a web component that “just works” like any other HTML element. Good libraries also have a high value-to-payload ratio - that is, they provide a lot of value for their download size. Libraries which support ES modules, Custom Element, Shadow DOM and Template are listed below. 16 | 17 | # Some web component libraries 18 | This list has been compiled by the community and can be modified via pull request under the community repository for this website. Projects are listed alphabetically and are known to support all four aspects of the web components specification. 19 | 20 | - Hybrids is a UI library for creating web components with simple and functional API. The library uses plain objects and pure functions for defining custom elements, which allow very flexible composition. It provides built-in cache mechanism, template engine based on tagged template literals, and integration with developer tools. 21 | - LitElement uses lit-html to render into the element's Shadow DOM and adds API to help manage element properties and attributes. LitElement reacts to changes in properties and renders declaratively using lit-html. 22 | - Polymer is a web component library built by Google, with a simple element creation API. Polymer offers one- and two-way data binding into element templates, and provides shims for better cross-browser performance. 23 | - Skate.js is a library built on top of the W3C web component specs that enables you to write functional and performant web components with a very small footprint. Skate is inherently cross-framework compatible. For example, it works seamlessly with - and complements - React and other frameworks. 24 | - Slim.js Slim.js is a lightweight web component library that provides extended capabilities for components, such as data binding, using es6 native class inheritance. This library is focused for providing the developer the ability to write robust and native web components without the hassle of dependencies and an overhead of a framework. 25 | - Stencil is an opensource compiler that generates standards-compliant web components. -------------------------------------------------------------------------------- /docs/about/resources.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layout-about.njk 3 | --- 4 | 5 | # Resources 6 | 7 | The WebComponents.org Resources section is a place to showcase useful tools and boilerplates to easily start hacking on your own custom elements. 8 | 9 | ## 1. Learn 10 | Web Components is a set of specs that introduce powerful new capabilities to the web platform. Before getting started with your first custom element, it will be helpful to understand the scope of these new features. The Introduction section contains an overview of these APIs. The Community section is also a great way to catch up on the latest goings-on in the Web Components world. We’d also recommend starting out by reading the Getting Started sections of: 11 | 12 | - Polymer's documentation; 13 | - Slim.js's documentation. 14 | - Skate.js's documentation. 15 | These will give you an idea on how these libraries for building web components work and what might be best for you. Another incredible resource is the web-components-todo repo which has the same to-do list app created in an ever growing list of web component and component compatible library methodologies. It's a great way to learn from the differences in techniques across libraries and see which one is right for your needs. 16 | 17 | ## 2. Create 18 | Once you’ve learned about Web Components, it's time to create your own element! There are a number of different jumping-off points for getting started using a Web Component library, or just using the vanilla Web Component APIs directly: 19 | 20 | - Polymer Boilerplate 21 | - VanillaJS Boilerplate. 22 | In these boilerplates, we solve the same problem using different libraries (Polymer / SkateJS / LitElement / SlimJS) or no library at all (VanillaJS), with the same tools and directory structure. 23 | 24 | We encourage a series of best practices like setting up a live demo, documenting your API, maintaining a changelog for release purposes, and sharing your component on NPM. The boilerplates form small, opinionated starter-kits with all you need included, from polyfills to automated tasks. 25 | 26 | You’ll still need to make some manual changes after forking each boilerplate, like changing an element's name in different files. In order to automate this process, we created a Yeoman Generator and a Slush Generator that can scaffold a web component using the command-line: 27 | 28 | - Element Generator for Yeoman 29 | - Element Generator for Slush 30 | - RHElement Generator 31 | The generators help ensure an even more seamless start, helping with tasks like validating your element's name according to W3C's spec rules and checking if there's a similarly-named project on NPM. 32 | 33 | Some projects also have command-line tools to help automate the scaffolding of web components and applications: 34 | 35 | - Polymer CLI - CLI + build Polymer 3 & scaffold full applications 36 | - StencilJS - CLI & Compiler to generate VanillaJS elements 37 | - Web Component Factory - CLI to produce boilerplate VanillaJS, SlimJS, StencilJS, Polmer 3, LitElement 38 | 39 | ## 3. Share 40 | Now that you’ve finished your element it's time to share it with the world! The web component ecosystem is growing quickly, and there are thousands of other developers out there who may benefit from your work. 41 | 42 | The best way to share a component is by making it available for use with one of the current JavaScript package managers. Currently most web component libraries have great support for Bower, and are working on improving support for npm. 43 | 44 | And make sure to publish your element to webcomponents.org! Check out the Publish page to learn how to publish your element. -------------------------------------------------------------------------------- /docs/about/specifications.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layout-about.njk 3 | --- 4 | 5 | # Specifications 6 | 7 | Web components is a meta-specification made possible by four other specifications: 8 | 9 | - The Custom Elements specification 10 | - The shadow DOM specification 11 | - The HTML Template specification 12 | - The ES Module specification 13 | 14 | These four specifications can be used on their own but combined allow developers to define their own tags (custom element), whose styles are encapsulated and isolated (shadow dom), that can be restamped many times (template), and have a consistent way of being integrated into applications (es module). 15 | 16 | ## The Custom Elements specification 17 | This section applies to the cross-browser version of the Custom Elements specification (v1). See Eric Bidelman’s articles on Custom Elements v1. 18 | 19 | The Custom Elements specification lays the foundation for designing and using new types of DOM elements that are fully-featured and conforming. Following the Custom Elements spec, authors can define behaviors and styles for new HTML elements. 20 | 21 | - Autonomous custom elements are new HTML tags, defined entirely by the author. They have none of the semantics of existing HTML elements, so all behaviors need to be defined by the author. 22 | - Customized built-ins extend existing HTML elements with custom functionality. They inherit semantics from the elements they extend. The specification for customized built-ins is still a work in progress, and at present is only supported by Chrome. 23 | 24 | ### Create a custom button as an autonomous custom element 25 | To create an autonomous custom element, extend HTMLElement. The Custom Elements syntax is: 26 | 27 | ```js 28 | class AutonomousButton extends HTMLElement { 29 | ... 30 | } 31 | customElements.define("autonomous-button", AutonomousButton); 32 | ``` 33 | 34 | To use the element: 35 | ```html 36 | Click Me :) 37 | ``` 38 | When the browser sees the tag, it constructs and renders a new instance of the AutonomousButton class. However, this element will not behave like an HTML 53 | ``` 54 | By extending HTMLButtonElement instead of HTMLElement, CustomizedButton inherits button semantics and behavior. 55 | 56 | *The long-term cross-browser support for customized built-in elements is a bit up in the air - please see https://github.com/w3c/webcomponents/issues/509 to learn more. 57 | 58 | ## The shadow DOM specification 59 | This section is a summary of the shadow DOM specification. See Eric Bidelman’s article on shadow DOM. 60 | 61 | The DOM (Document Object Model) is a representation of the structure of an html document. The DOM models a document as a tree, with elements in parent-child relationships. 62 | 63 | On its own, the DOM API contains no support for encapsulation. This makes it hard to develop custom elements as style information may “leak” into or out of other elements in the tree; or IDs may overlap between custom elements and other elements in the document. 64 | 65 | The shadow DOM API overcomes this limitation by letting you attach DOM subtrees to elements in a web document. These subtrees are encapsulated; style information inside them cannot apply to outside elements, and vice versa. 66 | 67 | ### Creating shadow DOM for a custom element 68 | In Shadow DOM, use the attachShadow() method to create shadow DOM: 69 | 70 | ```js 71 | const header = document.createElement('header'); 72 | const shadowRoot = header.attachShadow({mode: 'open'}); 73 | shadowRoot.innerHTML = '

Hello Shadow DOM

'; 74 | ``` 75 | 76 | ### Composition and slots 77 | By default, if an element has shadow DOM, the shadow tree is rendered instead of the element's children. To allow children to render, you need to add placeholders for them in your shadow tree. To do this in shadow DOM: 78 | 79 | Consider the following shadow tree for ``: 80 | 81 | ```html 82 |
83 |

84 | 85 |
86 | ``` 87 | 88 | The user can add children like this: 89 | 90 | ```html 91 | Shadow DOM 92 | The header renders as if the element was replaced by the children: 93 | 94 | 95 |
96 |

Shadow DOM

97 | 98 |
99 |
100 | ``` 101 | 102 | ### Styling 103 | Styles inside a shadow tree are scoped to the shadow tree, and don't affect elements outside the shadow tree. 104 | 105 | Styles outside the shadow tree also don't match selectors inside the shadow tree. However, inheritable style properties like color still inherit down from host to shadow tree. 106 | 107 | To style elements with a shadow root, you can use custom properties if the element’s author has defined them. 108 | 109 | ```html 110 | 114 | 115 | 116 | #shadow-root 117 | 120 |
Test
121 |
122 | ``` 123 | 124 | In this example, the
has a blue background, even though the div selector is less specific than the .test selector in the main document. That's because the main document selector doesn't match the
in the shadow DOM at all. On the other hand, the white text color set on the document body inherits down to and into its shadow root. 125 | 126 | # The ES Module specification 127 | The ES Module specification defines the inclusion and reuse of JS documents in other JS documents. 128 | 129 | ES Modules enable web components to be developed in a modular way that is in alignment with other industry accepted implementations for JavaScript application development. You can define the interface of your custom element in a JS file which is then included with an type="module" attribute. ES Module files are merged into one file client side or can be rolled up into single packages ahead of time. 130 | 131 | Supposing an element is defined in awesome-explosion.js, you would import it using one of the following script: 132 | 133 | ```html 134 | 135 | ... 136 | 141 | ``` 142 | 143 | Now you can use the awesome-explosion element in your own pages: 144 | 145 | ```html 146 | 147 | ... 148 | 149 | ``` 150 | 151 | ## The HTML Template specification 152 | The HTML template element specification defines how to declare fragments of markup that go unused at page load, but can be instantiated later on at runtime. There are no corresponding changes to HTML templates for cross-browser specifications. 153 | 154 | The content in this section is taken from Eric Bidelman’s article on the HTML Template specification. 155 | 156 | The template element is used to declare fragments of HTML that can be cloned and inserted in the document by script. 157 | 158 | Content between tags 159 | 160 | - Will not render until it is activated 161 | - Has no effect on other parts of the page - scripts won’t run, images won’t load, audio won’t play - until activated 162 | - Will not appear in the DOM 163 | 164 | Templates can be placed anywhere in , or and can contain any content that is allowed in those elements. 165 | 166 | To declare a template: 167 | 168 | ```html 169 | 173 | ``` 174 | 175 | To use the template: 176 | 177 | ```js 178 | var t = document.querySelector('#mytemplate'); 179 | // Populate the src at runtime. 180 | t.content.querySelector('img').src = 'logo.png'; 181 | 182 | var clone = document.importNode(t.content, true); 183 | document.body.appendChild(clone); 184 | ``` -------------------------------------------------------------------------------- /docs/articles/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layout-articles.njk 3 | --- 4 | 5 | # Articles 6 | 7 | Welcome to our articles this is about ... 8 | -------------------------------------------------------------------------------- /docs/articles/main/getting-started.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layout-articles.njk 3 | --- 4 | 5 | # Main: Getting Started 6 | 7 | hey there 👋 8 | -------------------------------------------------------------------------------- /docs/articles/main/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layout-articles.njk 3 | --- 4 | 5 | # Main 6 | -------------------------------------------------------------------------------- /docs/articles/using/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layout-articles.njk 3 | --- 4 | 5 | # Using Web Components 6 | -------------------------------------------------------------------------------- /docs/articles/using/styling-shadow.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layout-articles.njk 3 | --- 4 | 5 | # Using Web Components: Styling Components Using Shadow DOM 6 | 7 | Scoping is the main feature of shadow DOM as it allows for a true separation of concerns between the page styles and the component styles. 8 | However, if shadow DOM was completely unaffected by external styles it would severely limit its use cases. 9 | This article will guide you through the different ways you can style components which are using shadow DOM. 10 | 11 | > Note: Whether you can use any of the following options or not will depend on how the component you're using is implemented. 12 | > Please refer to the component's documentation to see what options are supported. 13 | > For more information on designing a component's CSS API check our guide on shadow DOM for component authors. 14 | 15 | ## Style inheritance 16 | 17 | The most basic way you can style content inside shadow DOM is through style inheritance. 18 | Style inheritance for web components using shadow DOM works the same way as it works for any other element. 19 | This means any CSS property that's inheritable, such as `font-size` or `color`, will also apply to shadow DOM content as long as it's not already being used. 20 | 21 | For example, if you had this style applied to your light DOM: 22 | 23 | ```css 24 | body { 25 | font-family: sans-serif; 26 | font-size: 16px; 27 | color: brown; 28 | margin: 0.5rem; 29 | } 30 | ``` 31 | 32 | And used a `my-element` component which has the following shadow DOM: 33 | 34 | ```html 35 | 40 |

This text will inherit the color.

41 |

This text will be green.

42 | ``` 43 | 44 | The following would happen: 45 | 46 | - Both texts inside `my-element` would have their `font-family` and `font-size` match the one set to the whole page. 47 | - The first text would also change it color to brown, but the second would be green as the `color` for it was defined inside the shadow DOM. 48 | - The `margin` for `my-element` would be unaffected as the `margin` property doesn't inherit. 49 | 50 | ## Host styles 51 | 52 | The host node of a component is the gateway between light DOM and the component's shadow DOM. 53 | As such, styles can be applied to it both from light DOM and from shadow DOM. 54 | But styles applied from light DOM will be prioritized over those applied from shadow DOM. 55 | 56 | For example, if you had a `my-element` component with the following shadow DOM: 57 | 58 | ```html 59 | 65 |
Some content
66 | ``` 67 | 68 | And you used it in the following way: 69 | 70 | ```html 71 | 79 | 80 | 81 | 82 | ``` 83 | 84 | The following will happen: 85 | 86 | - Both instances of the component will get an added padding of 8px. 87 | - Only the second one will get it's border changed to be a red dotted border. 88 | 89 | ## CSS variables 90 | 91 | CSS custom properties (colloquially referred to as CSS variables) are used to contain specific values so that they can be reused in other styles. 92 | They also happen to be one of the few ways to style content inside a shadow DOM tree from outside. 93 | 94 | For CSS variables to style content in a shadow DOM tree, component creators must have defined which variables will be used to style what. 95 | Think of this as a CSS API for the component. 96 | This way of styling shadow DOM is really useful for use cases such as theming and to give granular control over specific styles. 97 | 98 | For example, if you had a `my-button` component with the following shadow DOM: 99 | 100 | ```html 101 | 110 | 111 | ``` 112 | 113 | And you used it in the following way: 114 | 115 | ```html 116 | 123 | 124 | 125 | ``` 126 | 127 | The following will happen: 128 | 129 | - The first button will be rendered using the defaults for all CSS variables. So, it will be a green button with black text and a slight border radius. 130 | - The second button will have all the values defined in the CSS class applied to it. So, it will be a blue button with white text and no border radius. 131 | 132 | ## Shadow parts 133 | 134 | Shadow parts are currently the only other way besides using CSS variables to style content inside a shadow DOM tree from outside. 135 | But unlike CSS variables, shadow parts can be used to set any number of styles to a specific node in the shadow DOM tree. 136 | 137 | For example, if you had a `my-profile` component with the following shadow DOM: 138 | 139 | ```html 140 | 152 | 153 | 154 |
Some Name
155 | ``` 156 | 157 | And you used it in the following way: 158 | 159 | ```html 160 | 171 | 172 | 173 | 174 | ``` 175 | 176 | The following will happen: 177 | 178 | - The first component will render with only the styles defined in the component code. So, a square 48x48 px image and a green text will display; 179 | - The second component will have both the styles in the component code and the styles from the document itself, but the styles from the document will have a higher priority. So, a round 48x48 px image with a purple border and a purple bold text will display. 180 | 181 | ## Slotted children 182 | 183 | Slots are used to place light DOM content into specific points of the shadow DOM tree. 184 | But content placed in slots isn't completely under the control of web component, so, you can style the slotted content from light DOM. 185 | 186 | Note that the web components can also style slotted content through the `::slotted()` selector, but those styles will have lower priority than styles applied in light DOM. 187 | 188 | For example, if you had a `my-card` component with the following shadow DOM: 189 | 190 | ```html 191 | 206 | 207 |
208 | 209 |
210 |
211 | 212 |
213 | ``` 214 | 215 | And you used it in the following way: 216 | 217 | ```html 218 | 229 | 230 | 231 | Header 232 |
This is some content
233 |
234 | 235 | Header 236 |
237 | This is some content 238 |
239 |
240 | ``` 241 | 242 | The following will happen: 243 | 244 | - The first component will render with only the styles defined in the component code. So, the header will be bigger and underlined and the content will have a red bold highlighted part. 245 | - The second component will mix the light DOM and shadow DOM styles again and the light DOM styles will be prioritized once more. So, the header will keep its size but without the underline and the content will have an extra padding and change the highlight color to navy. 246 | 247 | ## A full example 248 | 249 | So far, we went through all the ways to style a web component. 250 | Let's now see an example of how to style an actual component using every one of those options. 251 | 252 | Note that not every component will or must have every single customization option enabled. 253 | It's mostly up to the component's developers to define their CSS API based on factors such as: the component spec and architecture, their target browser versions, integrations with other components, etc. 254 | 255 | For this example, we'll be using a component that can be styled using every option. 256 | The component is `generic-switch` from the [generic components library](https://genericcomponents.netlify.app/generic-switch/demo/index.html) by Pascal Schilp. 257 | The example uses the following options: 258 | 259 | 1. Style inheritance to set the `font-family`. 260 | 2. Host styles to set a `margin` for the component. 261 | 3. CSS variables to set `--generic-switch-focus` which controls the `box-shadow` applied when the component is focused. 262 | 4. Shadow parts to style different parts of the component such as the label, switch track, and switch thumb. 263 | 5. Styles applied to the SVG placed inside the label slot. 264 | 265 | 272 | -------------------------------------------------------------------------------- /docs/assets/icons/icon-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webcomponents-cg/docs-and-guides/5f76ab26cc291866916d642e4b59ffef8f06a7e4/docs/assets/icons/icon-128x128.png -------------------------------------------------------------------------------- /docs/assets/icons/icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webcomponents-cg/docs-and-guides/5f76ab26cc291866916d642e4b59ffef8f06a7e4/docs/assets/icons/icon-144x144.png -------------------------------------------------------------------------------- /docs/assets/icons/icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webcomponents-cg/docs-and-guides/5f76ab26cc291866916d642e4b59ffef8f06a7e4/docs/assets/icons/icon-152x152.png -------------------------------------------------------------------------------- /docs/assets/icons/icon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webcomponents-cg/docs-and-guides/5f76ab26cc291866916d642e4b59ffef8f06a7e4/docs/assets/icons/icon-16x16.png -------------------------------------------------------------------------------- /docs/assets/icons/icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webcomponents-cg/docs-and-guides/5f76ab26cc291866916d642e4b59ffef8f06a7e4/docs/assets/icons/icon-192x192.png -------------------------------------------------------------------------------- /docs/assets/icons/icon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webcomponents-cg/docs-and-guides/5f76ab26cc291866916d642e4b59ffef8f06a7e4/docs/assets/icons/icon-32x32.png -------------------------------------------------------------------------------- /docs/assets/icons/icon-384x384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webcomponents-cg/docs-and-guides/5f76ab26cc291866916d642e4b59ffef8f06a7e4/docs/assets/icons/icon-384x384.png -------------------------------------------------------------------------------- /docs/assets/icons/icon-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webcomponents-cg/docs-and-guides/5f76ab26cc291866916d642e4b59ffef8f06a7e4/docs/assets/icons/icon-512x512.png -------------------------------------------------------------------------------- /docs/assets/icons/icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webcomponents-cg/docs-and-guides/5f76ab26cc291866916d642e4b59ffef8f06a7e4/docs/assets/icons/icon-72x72.png -------------------------------------------------------------------------------- /docs/assets/icons/icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webcomponents-cg/docs-and-guides/5f76ab26cc291866916d642e4b59ffef8f06a7e4/docs/assets/icons/icon-96x96.png -------------------------------------------------------------------------------- /docs/assets/style.css: -------------------------------------------------------------------------------- 1 | html { 2 | --primary-color: #3f93ce; 3 | --primary-color-darker: #1d3557; 4 | --primary-color-lighter: #62a9dc; 5 | } 6 | 7 | #footer-badges img, 8 | #footer-badges svg { 9 | max-width: 145px; 10 | max-height: 3em; 11 | } 12 | 13 | @media (prefers-color-scheme: dark) { 14 | /* TODO: dark theme markdown colours for code blocks */ 15 | html { 16 | --primary-text-color: #eee; 17 | 18 | /* Contrast colors */ 19 | --contrast-color-light: #fff; 20 | --contrast-color-dark: #1d3557; 21 | 22 | /* background-colors */ 23 | --page-background: #212121; 24 | --footer-background: #333; 25 | 26 | /* typography */ 27 | --text-color: white; 28 | 29 | /* markdown */ 30 | --markdown-octicon-link: white; 31 | --markdown-syntax-background-color: #a0a0a0; 32 | --markdown-link-color: #c9e3ff; 33 | --markdown-blockquote-color: #c9e3ff; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /docs/assets/webmanifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Webcomponents Community Group", 3 | "short_name": "WC-CG", 4 | "theme_color": "#3f93ce", 5 | "background_color": "#fff", 6 | "display": "browser", 7 | "orientation": "portrait", 8 | "scope": "/", 9 | "start_url": "/", 10 | "icons": [ 11 | { 12 | "src": "/_merged_assets/icons/icon-72x72.png", 13 | "sizes": "72x72", 14 | "type": "image/png" 15 | }, 16 | { 17 | "src": "/_merged_assets/icons/icon-96x96.png", 18 | "sizes": "96x96", 19 | "type": "image/png" 20 | }, 21 | { 22 | "src": "/_merged_assets/icons/icon-128x128.png", 23 | "sizes": "128x128", 24 | "type": "image/png" 25 | }, 26 | { 27 | "src": "/_merged_assets/icons/icon-144x144.png", 28 | "sizes": "144x144", 29 | "type": "image/png" 30 | }, 31 | { 32 | "src": "/_merged_assets/icons/icon-152x152.png", 33 | "sizes": "152x152", 34 | "type": "image/png" 35 | }, 36 | { 37 | "src": "/_merged_assets/icons/icon-192x192.png", 38 | "sizes": "192x192", 39 | "type": "image/png" 40 | }, 41 | { 42 | "src": "/_merged_assets/icons/icon-384x384.png", 43 | "sizes": "384x384", 44 | "type": "image/png" 45 | }, 46 | { 47 | "src": "/_merged_assets/icons/icon-512x512.png", 48 | "sizes": "512x512", 49 | "type": "image/png" 50 | }, 51 | { 52 | "src": "/_merged_assets/icons/logo.svg" 53 | } 54 | ] 55 | } 56 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Web Components CG 3 | layout: layout-home.njk 4 | slogan: We care about web components. 5 | callToActionItems: 6 | - text: Read Articles 7 | href: /articles/ 8 | reasonHeader: Why a Community Group? 9 | reasons: 10 | - header: Connect 11 | text: This group is for collaboration between people working on web components libraries, tools, documentation and standards. 12 | - header: Collaborate 13 | text: Areas we expect to work on include gap analysis, design principles, common protocols, discoverability and quality, documentation, tooling, and more. 14 | - header: Common Problems 15 | text: We will work together on projects of shared interest in order to enhance interoperability, solve common problems, build shared community resources, and ultimately continue to grow a cooperative, productive, and happy web components ecosystem. 16 | --- 17 | 18 | ## Collaboration Areas 19 | 20 | There are many areas we can collaborate on. In some areas work is already being done, and in others we'd like to start. Visit the issue labels we've created below to see conversations already in flight, or to bring ideas you have to the community by creating new ones. 21 | 22 | - **[Polyfills](https://github.com/w3c/webcomponents-cg/labels/polyfills)** - we will continually need to keep polyfills up-to-date to support new standards like element internals, declarative shadow DOM, scoped custom elements, etc. 23 | 24 | - **[Common Protocols](https://github.com/w3c/webcomponents-cg/labels/common-protocols)** - it's possible to implement many of the cross-component coordination features that frameworks provide (SSR, context, DI, async-work coordination) with common patterns. These patterns will be much more impactful with community specifications that components can implement to ensure interoperability. 25 | 26 | - **[Design Principles](https://github.com/w3c/webcomponents-cg/labels/design-principles)** - API design is one of the hardest aspects of authoring any public-facing software artifact, and web components are no exception. Following platform conventions can be especially difficult when precedent is contradictory or nonexistent. Combining the various guidelines and serializing the de facto collective wisdom could assist in both guiding developers on how to produce high quality web components, as well as evaluating existing work, to facilitate discoverability of high quality components. 27 | 28 | - **[Documentation](https://github.com/w3c/webcomponents-cg/labels/documentation)** - Many concepts, techniques, and motivations for web components apply regardless of whether (and which) tools and libraries are being used to produce components. MDN is a great place for reference-oriented and, increasingly, guide-style documentation, but not for everything. Notably, web components lack a great canonical landing page that explains what they are and why one would use them. 29 | 30 | - **[Discoverability and Quality](https://github.com/w3c/webcomponents-cg/labels/discovery-and-quality)** - Increase visibility of good components, making it easier to catalog, evaluate, demo, and distribute web components to a wider audience, by providing an ever-expanding collection of reviewed and critiqued components to which the community can contribute samples and reviews. 31 | 32 | - **[Utilities](https://github.com/w3c/webcomponents-cg/labels/utilities)** - Many runtime utilities can work across web component implementations. Things like framework adapters (especially React), testing utilities (shadow piercing selectors), mixins that implement additional lifecycles (children changed, first connected), lazy definition loaders, theming, etc. 33 | 34 | - **[Metadata](https://github.com/w3c/webcomponents-cg/labels/metadata)** - Interop brings additional component documentation needs, which we are beginning to address with custom-elements-json. 35 | 36 | - **[Tools](https://github.com/w3c/webcomponents-cg/labels/tools)** - Some parts of static analyzers, linters, documentation generators, etc., may be able to be shared. A common and truly library-agnostic catalog would be massively beneficial to the community. 37 | 38 | - **[Standards Advancement](https://github.com/w3c/webcomponents-cg/labels/standards-advancement)** - Identify and prioritize gaps in the relevant technologies that prevent web components from reaching their full potential and work together with standards groups to address them (gap analysis). 39 | 40 | - **[Conferences and Meetups](https://github.com/w3c/webcomponents-cg/labels/conferences-and-meetups)** - Organize conferences and meetups that include topics and participants from across the web components ecosystem. 41 | 42 | ## Meetings 43 | 44 | The Web Components Community Group holds [a shared calendar](https://calendar.google.com/calendar/embed?src=o25bim5rvcu42mfnqilirpmp44%40group.calendar.google.com) of its meetings and events. An ics file is [available here](https://calendar.google.com/calendar/ical/o25bim5rvcu42mfnqilirpmp44%40group.calendar.google.com/public/basic.ics). 45 | 46 | --- 47 | 48 | A repository for the [Web Components Community Group](https://www.w3.org/community/webcomponents/) 49 | -------------------------------------------------------------------------------- /docs/light-dark.css: -------------------------------------------------------------------------------- 1 | html { 2 | --primary-color: #e63946; 3 | --primary-color-lighter: #e25761; 4 | --primary-color-darker: #a22831; 5 | --primary-color-accent: #cee5f6; 6 | --primary-text-color: #2c3e50; 7 | --primary-lines-color: #ccc; 8 | 9 | /* Contrast colors */ 10 | --contrast-color-light: #fff; 11 | --contrast-color-dark: #1d3557; 12 | 13 | /* background-colors */ 14 | --page-background: white; 15 | --footer-background: rgba(0, 0, 0, 0.1); 16 | 17 | /* typography */ 18 | --text-color: black; 19 | --primary-font-family: 'Open Sans', sans-serif; 20 | --secondary-font-family: 'Montserrat', sans-serif; 21 | --monospace-font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', 'Courier', monospace; 22 | } 23 | 24 | html.dark { 25 | --primary-color: #e63946; 26 | --primary-color-lighter: #e25761; 27 | --primary-color-darker: #a22831; 28 | --primary-color-accent: #cee5f6; 29 | --primary-text-color: #eee; 30 | 31 | /* Contrast colors */ 32 | --contrast-color-light: #fff; 33 | --contrast-color-dark: #1d3557; 34 | 35 | /* background-colors */ 36 | --page-background: #333; 37 | --footer-background: #4f4f4f; 38 | 39 | /* typography */ 40 | --text-color: white; 41 | 42 | /* markdown */ 43 | --markdown-octicon-link: white; 44 | --markdown-syntax-background-color: #a0a0a0; 45 | --markdown-link-color: #fb7881; 46 | --markdown-blockquote-color: #c9e3ff; 47 | } 48 | 49 | 50 | -------------------------------------------------------------------------------- /docs/markdown.css: -------------------------------------------------------------------------------- 1 | 2 | @font-face { 3 | font-family: octicons-link; 4 | src: 5 | url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAZwABAAAAAACFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEU0lHAAAGaAAAAAgAAAAIAAAAAUdTVUIAAAZcAAAACgAAAAoAAQAAT1MvMgAAAyQAAABJAAAAYFYEU3RjbWFwAAADcAAAAEUAAACAAJThvmN2dCAAAATkAAAABAAAAAQAAAAAZnBnbQAAA7gAAACyAAABCUM+8IhnYXNwAAAGTAAAABAAAAAQABoAI2dseWYAAAFsAAABPAAAAZwcEq9taGVhZAAAAsgAAAA0AAAANg.heading-wrapper:has(> h4)a91oaGVhAAADCAAAABoAAAAkCA8DRGhtdHgAAAL8AAAADAAAAAwGAACfbG9jYQAAAsAAAAAIAAAACABiATBtYXhwAAACqAAAABgAAAAgAA8ASm5hbWUAAAToAAABQgAAAlXu73sOcG9zdAAABiwAAAAeAAAAME3QpOBwcmVwAAAEbAAAAHYAAAB/aFGpk3jaTY6xa8JAGMW/O62BDi0tJLYQincXEypYIiGJjSgHniQ6umTsUEyLm5BV6NDBP8Tpts6F0v+k/0an2i+itHDw3v2+9+DBKTzsJNnWJNTgHEy4BgG3EMI9DCEDOGEXzDADU5hBKMIgNPZqoD3SilVaXZCER3/I7AtxEJLtzzuZfI+VVkprxTlXShWKb3TBecG11rwoNlmmn1P2WYcJczl32etSpKnziC7lQyWe1smVPy/Lt7Kc+0vWY/gAgIIEqAN9we0pwKXreiMasxvabDQMM4riO+qxM2ogwDGOZTXxwxDiycQIcoYFBLj5K3EIaSctAq2kTYiw+ymhce7vwM9jSqO8JyVd5RH9gyTt2+J/yUmYlIR0s04n6+7Vm1ozezUeLEaUjhaDSuXHwVRgvLJn1tQ7xiuVv/ocTRF42mNgZGBgYGbwZOBiAAFGJBIMAAizAFoAAABiAGIAznjaY2BkYGAA4in8zwXi+W2+MjCzMIDApSwvXzC97Z4Ig8N/BxYGZgcgl52BCSQKAA3jCV8CAABfAAAAAAQAAEB42mNgZGBg4f3vACQZQABIMjKgAmYAKEgBXgAAeNpjYGY6wTiBgZWBg2kmUxoDA4MPhGZMYzBi1AHygVLYQUCaawqDA4PChxhmh/8ODDEsvAwHgMKMIDnGL0x7gJQCAwMAJd4MFwAAAHjaY2BgYGaA4DAGRgYQkAHyGMF8NgYrIM3JIAGVYYDT+AEjAwuDFpBmA9KMDEwMCh9i/v8H8sH0/4dQc1iAmAkALaUKLgAAAHjaTY9LDsIgEIbtgqHUPpDi3gPoBVyRTmTddOmqTXThEXqrob2gQ1FjwpDvfwCBdmdXC5AVKFu3e5MfNFJ29KTQT48Ob9/lqYwOGZxeUelN2U2R6+cArgtCJpauW7UQBqnFkUsjAY/kOU1cP+DAgvxwn1chZDwUbd6CFimGXwzwF6tPbFIcjEl+vvmM/byA48e6tWrKArm4ZJlCbdsrxksL1AwWn/yBSJKpYbq8AXaaTb8AAHja28jAwOC00ZrBeQNDQOWO//sdBBgYGRiYWYAEELEwMTE4uzo5Zzo5b2BxdnFOcALxNjA6b2ByTswC8jYwg0VlNuoCTWAMqNzMzsoK1rEhNqByEyerg5PMJlYuVueETKcd/89uBpnpvIEVomeHLoMsAAe1Id4AAAAAAAB42oWQT07CQBTGv0JBhagk7HQzKxca2sJCE1hDt4QF+9JOS0nbaaYDCQfwCJ7Au3AHj+LO13FMmm6cl7785vven0kBjHCBhfpYuNa5P.heading-wrapper:has(> h1)c0e2Xu3jEvWG7UdPDLZ4N92nOm+EBXuAbHmIMSRMs+4aUEd4Nd3CHD8NdvOLTsA2GL8M9PODbcL+hD7C1xoaHeLJSEao0FEW14ckxC+TU8TxvsY6X0eLPmRhry2WVioLpkrbp84LLQPGI7c6sOiUzpWIWS5GzlSgUzzLBSikOPFTOXqly7rqx0Z1Q5BAIoZBSFihQYQOOBEdkCOgXTOHA07HAGjGWiIjaPZNW13/+lm6S9FT7rLHFJ6fQbkATOG1j2OFMucKJJsxIVfQORl+9Jyda6Sl1dUYhSCm1dyClfoeDve4qMYdLEbfqHf3O/AdDumsjAAB42mNgYoAAZQYjBmyAGYQZmdhL8zLdDEydARfoAqIAAAABAAMABwAKABMAB///AA8AAQAAAAAAAAAAAAAAAAABAAAAAA==) 6 | format('woff'); 7 | } 8 | 9 | .markdown-body .octicon { 10 | display: inline-block; 11 | fill: currentColor; 12 | vertical-align: text-bottom; 13 | } 14 | 15 | .markdown-body .anchor { 16 | float: left; 17 | line-height: 1; 18 | margin-left: -20px; 19 | padding-right: 4px; 20 | } 21 | 22 | .markdown-body .anchor:focus { 23 | outline: none; 24 | } 25 | 26 | h1, h2, h3, h4, h5, h6 { 27 | font-size: inherit; 28 | margin: 0; 29 | } 30 | 31 | .markdown-body .heading-wrapper:has(> h1) .octicon-link, 32 | .markdown-body .heading-wrapper:has(> h2) .octicon-link, 33 | .markdown-body .heading-wrapper:has(> h3) .octicon-link, 34 | .markdown-body .heading-wrapper:has(> h4) .octicon-link, 35 | .markdown-body .heading-wrapper:has(> h5) .octicon-link, 36 | .markdown-body .heading-wrapper:has(> h6) .octicon-link { 37 | color: var(--markdown-octicon-link, #1b1f23); 38 | vertical-align: middle; 39 | } 40 | 41 | .markdown-body .heading-wrapper:has(> h1):hover .anchor, 42 | .markdown-body .heading-wrapper:has(> h2):hover .anchor, 43 | .markdown-body .heading-wrapper:has(> h3):hover .anchor, 44 | .markdown-body .heading-wrapper:has(> h4):hover .anchor, 45 | .markdown-body .heading-wrapper:has(> h5):hover .anchor, 46 | .markdown-body .heading-wrapper:has(> h6):hover .anchor { 47 | text-decoration: none; 48 | } 49 | 50 | .markdown-body .heading-wrapper:has(> h1):focus-within .anchor .octicon-link, 51 | .markdown-body .heading-wrapper:has(> h2):focus-within .anchor .octicon-link, 52 | .markdown-body .heading-wrapper:has(> h3):focus-within .anchor .octicon-link, 53 | .markdown-body .heading-wrapper:has(> h4):focus-within .anchor .octicon-link, 54 | .markdown-body .heading-wrapper:has(> h5):focus-within .anchor .octicon-link, 55 | .markdown-body .heading-wrapper:has(> h6):focus-within .anchor .octicon-link, 56 | .markdown-body .heading-wrapper:has(> h1):hover .anchor .octicon-link, 57 | .markdown-body .heading-wrapper:has(> h2):hover .anchor .octicon-link, 58 | .markdown-body .heading-wrapper:has(> h3):hover .anchor .octicon-link, 59 | .markdown-body .heading-wrapper:has(> h4):hover .anchor .octicon-link, 60 | .markdown-body .heading-wrapper:has(> h5):hover .anchor .octicon-link, 61 | .markdown-body .heading-wrapper:has(> h6):hover .anchor .octicon-link { 62 | visibility: visible; 63 | } 64 | 65 | .markdown-body { 66 | -ms-text-size-adjust: 100%; 67 | -webkit-text-size-adjust: 100%; 68 | color: var(--markdown-body, --page-background); 69 | line-height: 1.5; 70 | font-family: var(--primary-font-family); 71 | font-size: 16px; 72 | line-height: 1.5; 73 | word-wrap: break-word; 74 | } 75 | 76 | .markdown-body details { 77 | display: block; 78 | } 79 | 80 | .markdown-body summary { 81 | display: list-item; 82 | } 83 | 84 | .markdown-body a { 85 | background-color: transparent; 86 | } 87 | 88 | .markdown-body a:active, 89 | .markdown-body a:hover { 90 | outline-width: 0; 91 | } 92 | 93 | .markdown-body strong { 94 | font-weight: inherit; 95 | font-weight: bolder; 96 | } 97 | 98 | .markdown-body .heading-wrapper:has(> h1) { 99 | font-size: 2em; 100 | margin: 0.67em 0; 101 | } 102 | 103 | .markdown-body img { 104 | border-style: none; 105 | } 106 | 107 | .markdown-body code, 108 | .markdown-body kbd, 109 | .markdown-body pre { 110 | font-family: monospace, monospace; 111 | font-size: 1em; 112 | } 113 | 114 | .markdown-body hr { 115 | box-sizing: content-box; 116 | height: 0; 117 | overflow: visible; 118 | } 119 | 120 | .markdown-body input { 121 | font: inherit; 122 | margin: 0; 123 | } 124 | 125 | .markdown-body input { 126 | overflow: visible; 127 | } 128 | 129 | .markdown-body [type='checkbox'] { 130 | box-sizing: border-box; 131 | padding: 0; 132 | } 133 | 134 | .markdown-body * { 135 | box-sizing: border-box; 136 | } 137 | 138 | .markdown-body input { 139 | font-family: inherit; 140 | font-size: inherit; 141 | line-height: inherit; 142 | } 143 | 144 | .markdown-body a { 145 | color: var(--markdown-link-color, #0366d6); 146 | text-decoration: none; 147 | } 148 | 149 | .markdown-body a:hover { 150 | text-decoration: underline; 151 | } 152 | 153 | .markdown-body strong { 154 | font-weight: 600; 155 | } 156 | 157 | .markdown-body hr { 158 | background: transparent; 159 | border: 0; 160 | border-bottom: 1px solid #dfe2e5; 161 | height: 0; 162 | margin: 15px 0; 163 | overflow: hidden; 164 | } 165 | 166 | .markdown-body hr::before { 167 | content: ''; 168 | display: table; 169 | } 170 | 171 | .markdown-body hr::after { 172 | clear: both; 173 | content: ''; 174 | display: table; 175 | } 176 | 177 | .markdown-body table { 178 | border-collapse: collapse; 179 | border-spacing: 0; 180 | } 181 | 182 | .markdown-body td, 183 | .markdown-body th { 184 | padding: 0; 185 | } 186 | 187 | .markdown-body details summary { 188 | cursor: pointer; 189 | } 190 | 191 | .markdown-body .heading-wrapper:has(> h1), 192 | .markdown-body .heading-wrapper:has(> h2), 193 | .markdown-body .heading-wrapper:has(> h3), 194 | .markdown-body .heading-wrapper:has(> h4), 195 | .markdown-body .heading-wrapper:has(> h5), 196 | .markdown-body .heading-wrapper:has(> h6) { 197 | font-family: var(--heading-font-family, var(--primary-font-family)); 198 | margin-bottom: 0; 199 | margin-top: 0; 200 | } 201 | 202 | .markdown-body .heading-wrapper:has(> h1) { 203 | font-size: 32px; 204 | } 205 | 206 | .markdown-body .heading-wrapper:has(> h1), 207 | .markdown-body .heading-wrapper:has(> h2) { 208 | font-weight: 600; 209 | } 210 | 211 | .markdown-body .heading-wrapper:has(> h2) { 212 | font-size: 24px; 213 | } 214 | 215 | .markdown-body .heading-wrapper:has(> h3) { 216 | font-size: 20px; 217 | } 218 | 219 | .markdown-body .heading-wrapper:has(> h3), 220 | .markdown-body .heading-wrapper:has(> h4) { 221 | font-weight: 600; 222 | } 223 | 224 | .markdown-body .heading-wrapper:has(> h4) { 225 | font-size: 16px; 226 | } 227 | 228 | .markdown-body .heading-wrapper:has(> h5) { 229 | font-size: 14px; 230 | } 231 | 232 | .markdown-body .heading-wrapper:has(> h5), 233 | .markdown-body .heading-wrapper:has(> h6) { 234 | font-weight: 600; 235 | } 236 | 237 | .markdown-body .heading-wrapper:has(> h6) { 238 | font-size: 12px; 239 | } 240 | 241 | .markdown-body p { 242 | margin-bottom: 10px; 243 | margin-top: 0; 244 | } 245 | 246 | .markdown-body blockquote { 247 | margin: 0; 248 | } 249 | 250 | .markdown-body ol, 251 | .markdown-body ul { 252 | margin-bottom: 0; 253 | margin-top: 0; 254 | padding-left: 0; 255 | } 256 | 257 | .markdown-body ol ol, 258 | .markdown-body ul ol { 259 | list-style-type: lower-roman; 260 | } 261 | 262 | .markdown-body ol ol ol, 263 | .markdown-body ol ul ol, 264 | .markdown-body ul ol ol, 265 | .markdown-body ul ul ol { 266 | list-style-type: lower-alpha; 267 | } 268 | 269 | .markdown-body dd { 270 | margin-left: 0; 271 | } 272 | 273 | .markdown-body code, 274 | .markdown-body pre { 275 | font-family: var(--monospace-font-family); 276 | font-size: 12px; 277 | } 278 | 279 | .markdown-body pre { 280 | margin-bottom: 0; 281 | margin-top: 0; 282 | } 283 | 284 | .markdown-body input::-webkit-inner-spin-button, 285 | .markdown-body input::-webkit-outer-spin-button { 286 | -webkit-appearance: none; 287 | appearance: none; 288 | margin: 0; 289 | } 290 | 291 | .markdown-body::before { 292 | content: ''; 293 | display: table; 294 | } 295 | 296 | .markdown-body::after { 297 | clear: both; 298 | content: ''; 299 | display: table; 300 | } 301 | 302 | .markdown-body > :first-child { 303 | margin-top: 0 !important; 304 | } 305 | 306 | .markdown-body > :last-child { 307 | margin-bottom: 0 !important; 308 | } 309 | 310 | .markdown-body a:not([href]) { 311 | color: inherit; 312 | text-decoration: none; 313 | } 314 | 315 | .markdown-body blockquote, 316 | .markdown-body dl, 317 | .markdown-body ol, 318 | .markdown-body p, 319 | .markdown-body pre, 320 | .markdown-body table, 321 | .markdown-body ul { 322 | margin-bottom: 16px; 323 | margin-top: 0; 324 | } 325 | 326 | .markdown-body hr { 327 | background-color: var(--markdown-divider-color, #e1e4e8); 328 | border: 0; 329 | height: 0.25em; 330 | margin: 24px 0; 331 | padding: 0; 332 | } 333 | 334 | .markdown-body blockquote { 335 | border-left: 0.25em solid var(--markdown-blockquote-border-color, #dfe2e5); 336 | color: var(--markdown-blockquote-color, #6a737d); 337 | padding: 0 1em; 338 | } 339 | 340 | .markdown-body blockquote > :first-child { 341 | margin-top: 0; 342 | } 343 | 344 | .markdown-body blockquote > :last-child { 345 | margin-bottom: 0; 346 | } 347 | 348 | .markdown-body kbd { 349 | background-color: var(--markdown-kbd-background-color, #fafbfc); 350 | border: 1px solid var(--markdown-kbd-border-color, #c6cbd1); 351 | border-bottom-color: var(--markdown-kbd-border-bottom-color, #959da5); 352 | border-radius: 3px; 353 | box-shadow: inset 0 -1px 0 var(--markdown-kbd-border-bottom-color, #959da5); 354 | color: var(--markdown-kbd-color, #444d56); 355 | display: inline-block; 356 | font-size: 11px; 357 | line-height: 10px; 358 | padding: 3px 5px; 359 | vertical-align: middle; 360 | } 361 | 362 | .markdown-body .heading-wrapper:has(> h1), 363 | .markdown-body .heading-wrapper:has(> h2), 364 | .markdown-body .heading-wrapper:has(> h3), 365 | .markdown-body .heading-wrapper:has(> h4), 366 | .markdown-body .heading-wrapper:has(> h5), 367 | .markdown-body .heading-wrapper:has(> h6) { 368 | font-weight: 600; 369 | line-height: 1.25; 370 | margin-bottom: 16px; 371 | margin-top: 24px; 372 | } 373 | 374 | .markdown-body .heading-wrapper:has(> h1) { 375 | font-size: 2em; 376 | } 377 | 378 | .markdown-body .heading-wrapper:has(> h1), 379 | .markdown-body .heading-wrapper:has(> h2) { 380 | border-bottom: 1px solid #eaecef; 381 | padding-bottom: 0.3em; 382 | } 383 | 384 | .markdown-body .heading-wrapper:has(> h2) { 385 | font-size: 1.5em; 386 | } 387 | 388 | .markdown-body .heading-wrapper:has(> h3) { 389 | font-size: 1.25em; 390 | } 391 | 392 | .markdown-body .heading-wrapper:has(> h4) { 393 | font-size: 1em; 394 | } 395 | 396 | .markdown-body .heading-wrapper:has(> h5) { 397 | font-size: 0.875em; 398 | } 399 | 400 | .markdown-body .heading-wrapper:has(> h6) { 401 | color: var(--markdown-heading-color-6, #6a737d); 402 | font-size: 0.85em; 403 | } 404 | 405 | .markdown-body ol, 406 | .markdown-body ul { 407 | padding-left: 2em; 408 | } 409 | 410 | .markdown-body ol ol, 411 | .markdown-body ol ul, 412 | .markdown-body ul ol, 413 | .markdown-body ul ul { 414 | margin-bottom: 0; 415 | margin-top: 0; 416 | } 417 | 418 | .markdown-body li { 419 | word-wrap: break-all; 420 | } 421 | 422 | .markdown-body li > p { 423 | margin-top: 16px; 424 | } 425 | 426 | .markdown-body li + li { 427 | margin-top: 0.25em; 428 | } 429 | 430 | .markdown-body dl { 431 | padding: 0; 432 | } 433 | 434 | .markdown-body dl dt { 435 | font-size: 1em; 436 | font-style: italic; 437 | font-weight: 600; 438 | margin-top: 16px; 439 | padding: 0; 440 | } 441 | 442 | .markdown-body dl dd { 443 | margin-bottom: 16px; 444 | padding: 0 16px; 445 | } 446 | 447 | .markdown-body table { 448 | display: block; 449 | overflow: auto; 450 | width: 100%; 451 | } 452 | 453 | .markdown-body table th { 454 | font-weight: 600; 455 | } 456 | 457 | .markdown-body table td, 458 | .markdown-body table th { 459 | border: 1px solid var(--markdown-table-border-color, #dfe2e5); 460 | padding: 6px 13px; 461 | } 462 | 463 | .markdown-body table tr { 464 | background-color: var(--markdown-table-background-color, #fff); 465 | border-top: 1px solid var(--markdown-table-border-color, #c6cbd1); 466 | } 467 | 468 | .markdown-body table tr:nth-child(2n) { 469 | background-color: var(--markdown-table-row-odd-background-color, #f6f8fa); 470 | } 471 | 472 | .markdown-body img { 473 | box-sizing: content-box; 474 | max-width: 100%; 475 | width: 100%; 476 | height: auto; 477 | } 478 | 479 | .markdown-body img[align='right'] { 480 | padding-left: 20px; 481 | } 482 | 483 | .markdown-body img[align='left'] { 484 | padding-right: 20px; 485 | } 486 | 487 | .markdown-body code { 488 | background-color: var(--markdown-code-background-color, rgba(27, 31, 35, 0.05)); 489 | border-radius: 3px; 490 | font-size: 85%; 491 | margin: 0; 492 | padding: 0.2em 0.4em; 493 | } 494 | 495 | .markdown-body pre { 496 | word-wrap: normal; 497 | } 498 | 499 | .markdown-body pre > code { 500 | background: transparent; 501 | border: 0; 502 | font-size: 100%; 503 | margin: 0; 504 | padding: 0; 505 | white-space: pre; 506 | word-break: normal; 507 | } 508 | 509 | .markdown-body .highlight { 510 | margin-bottom: 16px; 511 | } 512 | 513 | .markdown-body .highlight pre { 514 | margin-bottom: 0; 515 | word-break: normal; 516 | } 517 | 518 | .markdown-body .highlight pre, 519 | .markdown-body pre { 520 | background-color: var(--markdown-pre-background-color, #f6f8fa); 521 | border-radius: 3px; 522 | font-size: 85%; 523 | line-height: 1.45; 524 | overflow: auto; 525 | padding: 16px; 526 | } 527 | 528 | .markdown-body pre code { 529 | background-color: transparent; 530 | border: 0; 531 | display: inline; 532 | line-height: inherit; 533 | margin: 0; 534 | max-width: auto; 535 | overflow: visible; 536 | padding: 0; 537 | word-wrap: normal; 538 | } 539 | 540 | /***************** + */ 541 | 542 | code[class*='language-'], 543 | pre[class*='language-'] { 544 | color: var(--markdown-syntax-color, #393a34); 545 | font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace; 546 | direction: ltr; 547 | text-align: left; 548 | white-space: pre; 549 | word-spacing: normal; 550 | word-break: normal; 551 | tab-size: 4; 552 | hyphens: none; 553 | margin-bottom: 16px; 554 | padding: 16px; 555 | overflow: auto; 556 | font-size: 85%; 557 | line-height: 1.45; 558 | background-color: var(--markdown-syntax-background-color, #f6f8fa); 559 | border-radius: 3px; 560 | } 561 | 562 | .token.atrule { 563 | color: var(--markdown-syntax-atrule-color, #d73a49); 564 | } 565 | 566 | .token.attr-name { 567 | color: var(--markdown-syntax-attr-name-color, #d73a49); 568 | } 569 | 570 | .token.boolean { 571 | color: var(--markdown-syntax-boolean-color, #005cc5); 572 | } 573 | 574 | .token.class-name { 575 | color: var(--markdown-syntax-class-name-color, #6f42c1); 576 | } 577 | 578 | .token.constant { 579 | color: var(--markdown-syntax-constant-color, #005cc5); 580 | } 581 | 582 | .token.entity { 583 | color: var(--markdown-syntax-entity-color, #005cc5); 584 | } 585 | 586 | .token.function { 587 | color: var(--markdown-syntax-function-color, #6f42c1); 588 | } 589 | 590 | .token.inserted { 591 | color: var(--markdown-syntax-inserted-color, #005cc5); 592 | } 593 | 594 | .token.keyword { 595 | color: var(--markdown-syntax-keyword-color, #d73a49); 596 | } 597 | 598 | .token.number { 599 | color: var(--markdown-syntax-number-color, #005cc5); 600 | } 601 | 602 | .token.operator { 603 | color: var(--markdown-syntax-operator-color, #005cc5); 604 | } 605 | 606 | .token.property { 607 | color: var(--markdown-syntax-property-color, #005cc5); 608 | } 609 | 610 | .token.punctuation { 611 | color: var(--markdown-syntax-punctuation-color, #005cc5); 612 | } 613 | 614 | .token.regex { 615 | color: var(--markdown-syntax-regex-color, #032f62); 616 | } 617 | 618 | .token.selector { 619 | color: var(--markdown-syntax-selector-color, #22863a); 620 | } 621 | 622 | .token.symbol { 623 | color: var(--markdown-syntax-symbol-color, #005cc5); 624 | } 625 | 626 | .token.tag { 627 | color: var(--markdown-syntax-tag-color, #22863a); 628 | } 629 | 630 | .token.url { 631 | color: var(--markdown-syntax-url-color, #005cc5); 632 | } 633 | 634 | .token.variable { 635 | color: var(--markdown-syntax-variable-color, #005cc5); 636 | } 637 | 638 | .language-autohotkey .token.selector { 639 | color: var(--markdown-syntax-hotkey-selector-color, #d73a49); 640 | } 641 | 642 | .language-autohotkey .token.keyword { 643 | color: var(--markdown-syntax-keyword-color, #22863a); 644 | } 645 | 646 | -------------------------------------------------------------------------------- /docs/site.css: -------------------------------------------------------------------------------- 1 | /* smooth scroll only if there is no preference for reduced motion */ 2 | @media (prefers-reduced-motion: no-preference) { 3 | html { 4 | scroll-behavior: smooth; 5 | } 6 | } 7 | 8 | body { 9 | margin: 0; 10 | font-family: var(--primary-font-family); 11 | -webkit-font-smoothing: antialiased; 12 | -moz-osx-font-smoothing: grayscale; 13 | font-size: 16px; 14 | color: var(--primary-text-color); 15 | background-color: var(--page-background); 16 | display: flex; 17 | flex-flow: column; 18 | min-height: 100vh; 19 | max-width: 100vw; 20 | overflow-x: hidden; 21 | } 22 | 23 | * { 24 | box-sizing: border-box; 25 | } 26 | 27 | pre { 28 | overflow: auto; 29 | } 30 | 31 | .logo-link img { 32 | width: 30px; 33 | height: 30px; 34 | vertical-align: middle; 35 | } 36 | 37 | .sr-only { 38 | position: absolute; 39 | left: -10000px; 40 | top: auto; 41 | width: 1px; 42 | height: 1px; 43 | overflow: hidden; 44 | } 45 | 46 | .light-dark-switch { 47 | /* disabled for now */ 48 | display: none !important; 49 | } 50 | 51 | .light-dark-switch::part(button) { 52 | height: 20px; 53 | width: 40px; 54 | } 55 | 56 | .light-dark-switch::part(thumb) { 57 | right: 20px; 58 | border: solid 1px #4d4d4d; 59 | border-radius: 50%; 60 | width: calc(50% - 2px); 61 | height: calc(100% - 2px); 62 | background-color: white; 63 | } 64 | 65 | .light-dark-switch[checked]::part(thumb) { 66 | right: 0; 67 | } 68 | 69 | .light-dark-switch::part(track) { 70 | border-top-left-radius: 10px; 71 | border-bottom-left-radius: 10px; 72 | border-top-right-radius: 10px; 73 | border-bottom-right-radius: 10px; 74 | background-color: #4d4d4d; 75 | } 76 | 77 | .light-dark-switch[checked]::part(track)::before { 78 | content: '🌞'; 79 | position: absolute; 80 | left: 2px; 81 | top: 4px; 82 | line-height: 14px; 83 | } 84 | 85 | .light-dark-switch::part(track)::before { 86 | content: '🌛'; 87 | position: absolute; 88 | left: 22px; 89 | top: 4px; 90 | line-height: 14px; 91 | } 92 | 93 | .light-dark-switch { 94 | margin-right: 50px; 95 | 96 | --generic-switch-focus: 0 0 2px 3px #e63a46; 97 | } 98 | 99 | hr { 100 | border: none; 101 | height: 1px; 102 | background: #ccc; 103 | } 104 | 105 | /** LAYOUT ****************************************************************************************/ 106 | #content-wrapper .content-area, 107 | #main-header .content-area, 108 | #main-footer .content-area { 109 | padding: 0 20px; 110 | } 111 | 112 | #content-wrapper .content-area { 113 | display: flex; 114 | } 115 | 116 | @media screen and (min-width: 1024px) { 117 | #wrapper { 118 | max-width: 1200px; 119 | margin: 0 auto; 120 | } 121 | 122 | .content-area { 123 | max-width: 1200px; 124 | margin: 0 auto; 125 | } 126 | } 127 | 128 | /** HEADER ****************************************************************************************/ 129 | #main-header { 130 | align-items: center; 131 | padding: 20px 0; 132 | top: 0; 133 | position: sticky; 134 | z-index: 100; 135 | background-color: var(--page-background); 136 | box-shadow: 0 0 3px rgba(0, 0, 0, 0.3); 137 | } 138 | 139 | body[layout^='layout-home'] #main-header { 140 | position: relative; 141 | } 142 | 143 | #main-header .content-area { 144 | display: flex; 145 | justify-content: space-between; 146 | align-items: center; 147 | min-height: 30px; 148 | } 149 | 150 | #main-header a { 151 | text-decoration: none; 152 | color: var(--primary-text-color); 153 | transition: color 0.3s ease-in-out; 154 | font-weight: bold; 155 | order: 2; 156 | } 157 | 158 | #main-header a:hover { 159 | color: var(--primary-color); 160 | } 161 | 162 | body[layout^='layout-home'] #main-header a:hover { 163 | color: inherit; 164 | } 165 | 166 | #mobile-menu-trigger { 167 | color: inherit; 168 | border: none; 169 | width: 20px; 170 | height: 20px; 171 | box-sizing: content-box; 172 | background: none; 173 | padding: 0; 174 | } 175 | 176 | .social-link { 177 | display: none; 178 | } 179 | 180 | #main-header .logo-link { 181 | display: none; 182 | color: var(--primary-color); 183 | order: 0; 184 | } 185 | 186 | #main-header .search { 187 | order: 3; 188 | } 189 | 190 | #main-header .logo-link span { 191 | font-size: 19px; 192 | font-weight: bold; 193 | margin-left: 8px; 194 | vertical-align: middle; 195 | } 196 | 197 | #main-header .light-dark-switch { 198 | display: none; 199 | } 200 | 201 | @media screen and (min-width: 1024px) { 202 | .social-link { 203 | display: block; 204 | width: 30px; 205 | height: 30px; 206 | } 207 | 208 | .social-link img { 209 | width: 100%; 210 | } 211 | 212 | #main-header .content-area > * { 213 | margin-right: 50px; 214 | } 215 | 216 | #main-header .content-area > .social-link { 217 | margin-right: 15px; 218 | } 219 | 220 | #main-header .content-area > *:last-child { 221 | margin-right: 0; 222 | } 223 | 224 | #main-header .search { 225 | order: 1; 226 | } 227 | 228 | #mobile-menu-trigger { 229 | display: none; 230 | } 231 | 232 | #main-header .logo-link { 233 | display: block; 234 | margin-right: auto; 235 | } 236 | 237 | #main-header .light-dark-switch { 238 | display: block; 239 | } 240 | 241 | body[layout='layout-home-background'] #main-header a { 242 | color: var(--contrast-color-light, #fff); 243 | } 244 | 245 | body[layout='layout-home-background'] .social-link { 246 | color: var(--contrast-color-light, #fff); 247 | } 248 | } 249 | 250 | /** SIDEBAR ***************************************************************************************/ 251 | #sidebar { 252 | display: none; 253 | } 254 | 255 | #sidebar-nav { 256 | background: var(--page-background, #fff); 257 | width: 80%; 258 | height: 100%; 259 | position: fixed; 260 | top: 0; 261 | left: 0; 262 | max-height: 100vh; 263 | overflow: auto; 264 | } 265 | 266 | rocket-navigation .light-dark-switch { 267 | margin-bottom: 10px; 268 | } 269 | 270 | rocket-navigation .light-dark-switch::part(label) { 271 | order: 10; 272 | margin-left: 10px; 273 | } 274 | 275 | rocket-navigation a { 276 | text-decoration: none; 277 | color: var(--primary-text-color); 278 | } 279 | 280 | rocket-navigation a:hover { 281 | color: var(--primary-color); 282 | } 283 | 284 | /* line on the left to indicate current page */ 285 | rocket-navigation > ul > li > ul li.current ul li.anchor.current::before { 286 | content: ''; 287 | height: 1.6em; 288 | width: 3px; 289 | background: var(--primary-color); 290 | position: absolute; 291 | left: 0; 292 | margin-top: -2px; 293 | } 294 | 295 | rocket-navigation li { 296 | padding: 7px 0; 297 | } 298 | 299 | rocket-navigation > ul > li > ul li.current a:not(.anchor) { 300 | font-weight: bold; 301 | } 302 | 303 | rocket-navigation > ul > li > ul > li.current > ul > li > a { 304 | font-weight: normal; 305 | } 306 | 307 | rocket-navigation hr { 308 | margin: 30px -10px 10px -10px; 309 | } 310 | 311 | /* Hide below 3rd level by default */ 312 | rocket-navigation > ul > li > ul > li ul { 313 | display: none; 314 | } 315 | 316 | /* Only show below 3rd level if level above is active/current */ 317 | li.current > ul, 318 | li.active > ul { 319 | display: block; 320 | } 321 | 322 | rocket-navigation > ul > li > a { 323 | color: var(--primary-color); 324 | font-weight: bold; 325 | font-size: 18px; 326 | text-transform: uppercase; 327 | } 328 | 329 | rocket-navigation > ul > li > ul a { 330 | font-weight: normal; 331 | } 332 | 333 | rocket-navigation { 334 | overflow: auto; 335 | display: block; 336 | margin-top: 40px; 337 | padding: 0 20px; 338 | } 339 | 340 | rocket-navigation ul { 341 | padding: 7px 0 10px 15px; 342 | margin: 0; 343 | list-style-type: none; 344 | } 345 | 346 | rocket-navigation > ul { 347 | padding: 0; 348 | position: relative; 349 | } 350 | 351 | #sidebar-nav .logo-link { 352 | display: block; 353 | font-size: 18px; 354 | border-bottom: 1px solid #ccc; 355 | padding: 20px 0; 356 | padding-left: 10px; 357 | text-decoration: none; 358 | 359 | /* same as header */ 360 | box-shadow: 0 0 3px rgba(0, 0, 0, 0.3); 361 | color: var(--primary-text-color); 362 | font-weight: bold; 363 | } 364 | 365 | #sidebar-nav .logo-link span { 366 | padding-left: 10px; 367 | } 368 | 369 | #sidebar-nav li.anchor { 370 | padding: 4px 0; 371 | } 372 | 373 | #sidebar-nav li.anchor a { 374 | position: relative; 375 | } 376 | 377 | #sidebar-nav li.anchor:last-child { 378 | padding: 4px 0 0 0; 379 | } 380 | 381 | li.anchor { 382 | display: none; 383 | } 384 | 385 | li.current > ul > li.anchor { 386 | display: block; 387 | } 388 | 389 | .sidebar-bottom { 390 | padding-bottom: 10px; 391 | } 392 | 393 | @media screen and (min-width: 1024px) { 394 | #sidebar { 395 | position: sticky; 396 | height: 100%; 397 | left: 0; 398 | top: 70px; 399 | overflow-y: auto; 400 | scroll-behavior: smooth; 401 | min-width: 270px; 402 | z-index: 10; 403 | background: none; 404 | border: none; 405 | padding: 0; 406 | margin: 0; 407 | margin-right: 50px; 408 | } 409 | 410 | #sidebar .sidebar-bottom { 411 | display: none; 412 | } 413 | 414 | #sidebar hr { 415 | margin: 30px 0 10px 0; 416 | background: linear-gradient(90deg, rgba(204, 204, 204, 1) 0%, rgba(255, 255, 255, 0) 80%); 417 | } 418 | 419 | #sidebar-nav { 420 | width: 100%; 421 | position: static; 422 | max-height: calc(100vh - 70px); 423 | } 424 | 425 | #sidebar .logo-link { 426 | display: none; 427 | } 428 | 429 | rocket-navigation { 430 | padding: 0 25px 0 0; 431 | } 432 | 433 | body[layout='layout-sidebar'] #sidebar, 434 | body[layout='layout-index'] #sidebar { 435 | display: block; 436 | } 437 | } 438 | 439 | /* for blog detail page */ 440 | rocket-navigation h3 { 441 | font-family: var(--heading-font-family, var(--primary-font-family)); 442 | font-size: 16px; 443 | margin: 0 0 7px 0; 444 | } 445 | 446 | .sidebar-tags h3 { 447 | font-family: var(--heading-font-family, var(--primary-font-family)); 448 | margin-top: 30px; 449 | } 450 | 451 | .sidebar-tags .tags { 452 | display: flex; 453 | flex-wrap: wrap; 454 | } 455 | 456 | .sidebar-tags .tag { 457 | background: var(--sidebar-tag-background-color, #ccc); 458 | color: var(--sidebar-tag-color, var(--text-color)); 459 | margin: 5px 0 0 5px; 460 | padding: 5px 10px; 461 | box-sizing: content-box; 462 | border-radius: 20px; 463 | } 464 | 465 | /** MAIN ******************************************************************************************/ 466 | #content-wrapper { 467 | min-height: 60vh; 468 | } 469 | 470 | body[layout='layout-home'] #content-wrapper { 471 | margin-top: 0; 472 | } 473 | 474 | main { 475 | width: 100%; 476 | position: relative; 477 | 478 | /* makes sure that code blocks don't grow bigger then main => see https://css-tricks.com/preventing-a-grid-blowout/ */ 479 | min-width: 0; 480 | margin-top: 40px; 481 | } 482 | 483 | main > * { 484 | scroll-margin-top: 85px; 485 | } 486 | 487 | @media screen and (min-width: 1024px) { 488 | main { 489 | z-index: 50; 490 | } 491 | } 492 | 493 | .content-footer { 494 | border-top: 1px solid var(--primary-lines-color); 495 | margin-top: 100px; 496 | padding-top: 20px; 497 | text-align: center; 498 | } 499 | 500 | /** FOOTER ****************************************************************************************/ 501 | #main-footer { 502 | margin-top: 50px; 503 | border-top: 1px solid #eaeaea; 504 | background-color: var(--footer-background, rgba(0, 0, 0, 0.1)); 505 | color: var(--text-color); 506 | padding: 40px 0; 507 | flex-grow: 1; 508 | display: flex; 509 | flex-flow: column; 510 | justify-content: center; 511 | } 512 | 513 | #footer-menu .content-area { 514 | display: flex; 515 | justify-content: space-between; 516 | flex-direction: column; 517 | text-align: center; 518 | } 519 | 520 | @media screen and (min-width: 1024px) { 521 | #footer-menu .content-area { 522 | flex-direction: row; 523 | text-align: left; 524 | } 525 | } 526 | 527 | #footer-menu ul { 528 | list-style-type: none; 529 | padding: 0; 530 | } 531 | 532 | #footer-menu a { 533 | text-decoration: none; 534 | color: var(--primary-text-color); 535 | padding: 5px 0; 536 | display: block; 537 | } 538 | 539 | /** CALL TO ACTION ********************************************************************************/ 540 | 541 | .markdown-body .call-to-action-list { 542 | text-align: center; 543 | padding: 25px 0; 544 | } 545 | 546 | .markdown-body .call-to-action { 547 | display: inline-block; 548 | text-align: center; 549 | text-transform: uppercase; 550 | font-family: var(--secondary-font-family); 551 | font-size: 16px; 552 | font-weight: bold; 553 | vertical-align: middle; 554 | padding: 8px 24px; 555 | border: 1px solid var(--primary-color); 556 | border-radius: 24px; 557 | background: linear-gradient(to right, var(--primary-color-lighter), var(--primary-color)); 558 | text-shadow: var(--primary-color-darker) 1px 1px 1px; 559 | color: var(--contrast-color-light, #fff); 560 | text-decoration: none; 561 | } 562 | 563 | .markdown-body .call-to-action:hover, 564 | .markdown-body .call-to-action:focus { 565 | background: linear-gradient(to right, var(--primary-color), var(--primary-color-darker)); 566 | text-decoration: none; 567 | } 568 | 569 | .markdown-body .call-to-action:active { 570 | background: var(--primary-color-darker); 571 | } 572 | 573 | /** LAYOUT-INDEX ******************************************************************************************/ 574 | #layout-index-open-navigation { 575 | display: flex; 576 | width: 100%; 577 | align-items: center; 578 | justify-content: center; 579 | } 580 | 581 | #layout-index-open-navigation svg { 582 | width: 20px; 583 | margin-right: 20px; 584 | } 585 | 586 | @media screen and (min-width: 1024px) { 587 | #layout-index-open-navigation { 588 | display: none; 589 | } 590 | } 591 | 592 | /** HOME ******************************************************************************************/ 593 | 594 | .page-background { 595 | display: none; 596 | } 597 | 598 | body[layout^='layout-home'] main { 599 | padding-top: 50px; 600 | } 601 | 602 | body[layout^='layout-home'] .page-title { 603 | color: var(--primary-color); 604 | font-size: 32px; 605 | } 606 | 607 | body[layout^='layout-home'] .page-logo { 608 | display: block; 609 | margin: 0 auto; 610 | width: 35vw; 611 | max-width: 250px; 612 | color: var(--primary-color); 613 | } 614 | 615 | body[layout^='layout-home'] .page-title, 616 | body[layout^='layout-home'] .reason-header, 617 | body[layout^='layout-home'] .page-slogan { 618 | text-align: center; 619 | border-bottom: none; 620 | color: var(--text-color); 621 | } 622 | 623 | body[layout^='layout-home'] .page-slogan { 624 | font-size: 18px; 625 | } 626 | 627 | body[layout^='layout-home'] .reason-header { 628 | margin-top: 60px; 629 | } 630 | 631 | body[layout^='layout-home'] .reasons { 632 | display: grid; 633 | grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); 634 | column-gap: 100px; 635 | row-gap: 40px; 636 | color: var(--text-color); 637 | } 638 | 639 | body[layout^='layout-home'] .markdown-body .call-to-action { 640 | margin: 10px; 641 | } 642 | 643 | body[layout^='layout-home'] .markdown-body .call-to-action:nth-child(1) { 644 | margin-left: 0; 645 | } 646 | 647 | @media screen and (min-width: 380px) { 648 | body[layout^='layout-home'] #main-header { 649 | box-shadow: none; 650 | } 651 | 652 | body[layout^='layout-home'] .page-slogan { 653 | font-size: 25px; 654 | } 655 | 656 | body[layout^='layout-home'] .page-title { 657 | font-size: 50px; 658 | } 659 | } 660 | 661 | /** HOME WITH BACKGROUND **************************************************************************/ 662 | body[layout='layout-home-background'] .page-background { 663 | display: none; 664 | } 665 | 666 | @media screen and (min-width: 1024px) { 667 | body[layout='layout-home-background'] .page-title, 668 | body[layout='layout-home-background'] .page-slogan { 669 | text-align: left; 670 | } 671 | 672 | body[layout='layout-home-background'] .page-title { 673 | margin-top: 110px; 674 | } 675 | 676 | body[layout='layout-home-background'] .page-slogan { 677 | max-width: 500px; 678 | } 679 | 680 | body[layout='layout-home-background'] .markdown-body .call-to-action-list { 681 | text-align: left; 682 | } 683 | 684 | body[layout='layout-home-background'] #main-header { 685 | background: transparent; 686 | border-bottom: none; 687 | } 688 | 689 | body[layout='layout-home-background'] .page-background { 690 | display: block; 691 | position: absolute; 692 | top: -52px; 693 | right: -60px; 694 | z-index: -1; 695 | } 696 | 697 | body[layout='layout-home-background'] .page-logo { 698 | display: none; 699 | } 700 | 701 | body[layout='layout-home-background'] #main-header .logo-link { 702 | color: var(--contrast-color-dark, #000); 703 | } 704 | 705 | body[layout='layout-home-background'] #main-header .logo-link span { 706 | position: absolute; 707 | left: -10000px; 708 | top: auto; 709 | width: 1px; 710 | height: 1px; 711 | overflow: hidden; 712 | } 713 | } 714 | 715 | .visually-hidden { 716 | clip: rect(0 0 0 0); 717 | clip-path: inset(50%); 718 | height: 1px; 719 | overflow: hidden; 720 | position: absolute; 721 | white-space: nowrap; 722 | width: 1px; 723 | } 724 | 725 | /* // Anchor links */ 726 | /* // Based on https://smolcss.dev/#smol-article-anchors */ 727 | .heading-wrapper { 728 | display: grid; 729 | /* // anchor link on the far right for long wrapping headings */ 730 | grid-template-columns: minmax(auto, max-content) min-content; 731 | align-items: stretch; 732 | } 733 | 734 | .header-anchor { 735 | display: grid; 736 | justify-content: center; 737 | align-content: center; 738 | width: 32px; 739 | text-align: center; 740 | 741 | &:link, 742 | &:visited { 743 | padding: 0 0.25rem; 744 | border-radius: 0.3em; 745 | color: var(--color-meta); 746 | text-decoration: none; 747 | 748 | svg { 749 | fill: currentColor; 750 | stroke-linecap: round; 751 | stroke-linejoin: round; 752 | } 753 | } 754 | 755 | .heading-wrapper:hover &, 756 | &:hover, 757 | &:focus { 758 | color: var(--color-link-hover); 759 | background-color: var(--color-link-hover-bg); 760 | } 761 | } 762 | 763 | .heading-wrapper { 764 | grid-template-columns: min-content auto; 765 | } 766 | 767 | .header-anchor { 768 | grid-row-start: 1; 769 | margin-inline: -28px -16px; 770 | font-weight: normal; 771 | } -------------------------------------------------------------------------------- /docs/styles.css: -------------------------------------------------------------------------------- 1 | @import url('./light-dark.css'); 2 | @import url('./theme.css'); 3 | @import url('./site.css'); 4 | @import url('./markdown.css'); -------------------------------------------------------------------------------- /docs/theme.css: -------------------------------------------------------------------------------- 1 | html { 2 | --primary-color: #3f93ce; 3 | --primary-color-darker: #1d3557; 4 | --primary-color-lighter: #62a9dc; 5 | } 6 | 7 | #footer-badges img, 8 | #footer-badges svg { 9 | max-width: 145px; 10 | max-height: 3em; 11 | } 12 | 13 | @media (prefers-color-scheme: dark) { 14 | /* TODO: dark theme markdown colours for code blocks */ 15 | html { 16 | --primary-text-color: #eee; 17 | 18 | /* Contrast colors */ 19 | --contrast-color-light: #fff; 20 | --contrast-color-dark: #1d3557; 21 | 22 | /* background-colors */ 23 | --page-background: #212121; 24 | --footer-background: #333; 25 | 26 | /* typography */ 27 | --text-color: white; 28 | 29 | /* markdown */ 30 | --markdown-octicon-link: white; 31 | --markdown-syntax-background-color: #a0a0a0; 32 | --markdown-link-color: #c9e3ff; 33 | --markdown-blockquote-color: #c9e3ff; 34 | } 35 | } -------------------------------------------------------------------------------- /eleventy.config.js: -------------------------------------------------------------------------------- 1 | import syntaxHighlight from "@11ty/eleventy-plugin-syntaxhighlight"; 2 | import markdownIt from "markdown-it"; 3 | import markdownItAnchors from "markdown-it-anchor"; 4 | 5 | export default function(eleventyConfig) { 6 | let options = { 7 | html: true, 8 | breaks: true, 9 | linkify: true, 10 | }; 11 | 12 | const markdown = markdownIt(options).use(markdownItAnchors, { 13 | level: [1, 2, 3, 4], 14 | permalink: true, 15 | permalinkSymbol: '#', 16 | permalinkAttrs: () => ({ 'aria-label': '§' }), 17 | renderPermalink: (slug, opts, state, idx) => { 18 | // based on fifth version in 19 | // https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/ 20 | const linkContent = state.tokens[idx + 1].children[0].content; 21 | 22 | // Create the openning
for the wrapper 23 | const headingWrapperTokenOpen = Object.assign( 24 | new state.Token('div_open', 'div', 1), 25 | { 26 | attrs: [['class', 'heading-wrapper']], 27 | } 28 | ); 29 | // Create the closing
for the wrapper 30 | const headingWrapperTokenClose = Object.assign( 31 | new state.Token('div_close', 'div', -1), 32 | { 33 | attrs: [['class', 'heading-wrapper']], 34 | } 35 | ); 36 | 37 | // Create the tokens for the full accessible anchor link 38 | // 39 | // 42 | // 43 | // Section titled Your "own" platform is the nearest you can(get help to) setup 44 | // 45 | // 46 | const anchorTokens = [ 47 | Object.assign(new state.Token('link_open', 'a', 1), { 48 | attrs: [ 49 | ...(opts.permalinkClass ? [['class', opts.permalinkClass]] : []), 50 | ['href', opts.permalinkHref(slug, state)], 51 | ...Object.entries(opts.permalinkAttrs(slug, state)), 52 | ], 53 | }), 54 | Object.assign(new state.Token('span_open', 'span', 1), { 55 | attrs: [['aria-hidden', 'true']], 56 | }), 57 | 58 | // 59 | 60 | Object.assign(new state.Token('svg_open', 'svg', 1), { 61 | attrs: [ 62 | ['class', 'octicon octicon-link'], 63 | ['viewBox', '0 0 16 16'], 64 | ['aria-hidden', 'true'], 65 | ['width', '16'], 66 | ['height', '16'], 67 | ] 68 | }), 69 | Object.assign(new state.Token('path_open', 'path', 1), { 70 | attrs: [ 71 | ['fill-rule', 'evenodd'], 72 | ['d', 'M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'], 73 | ] 74 | }), 75 | 76 | // Object.assign(new state.Token('html_block', '', 0), { 77 | // content: opts.permalinkSymbol, 78 | // }), 79 | 80 | Object.assign(new state.Token('path_close', 'path', -1), {}), 81 | Object.assign(new state.Token('svg_open', 'svg', -1), {}), 82 | Object.assign(new state.Token('span_close', 'span', -1), {}), 83 | Object.assign(new state.Token('span_open', 'span', 1), { 84 | attrs: [['class', 'visually-hidden']], 85 | }), 86 | Object.assign(new state.Token('html_block', '', 0), { 87 | content: `Section titled ${linkContent}`, 88 | }), 89 | Object.assign(new state.Token('span_close', 'span', -1), {}), 90 | new state.Token('link_close', 'a', -1), 91 | ]; 92 | 93 | // idx is the index of the heading's first token 94 | // insert the wrapper opening before the heading 95 | state.tokens.splice(idx, 0, headingWrapperTokenOpen); 96 | // insert the anchor link tokens after the wrapper opening and the 3 tokens of the heading 97 | state.tokens.splice(idx + 3 + 1, 0, ...anchorTokens); 98 | // insert the wrapper closing after all these 99 | state.tokens.splice( 100 | idx + 3 + 1 + anchorTokens.length, 101 | 0, 102 | headingWrapperTokenClose 103 | ); 104 | }, 105 | }); 106 | 107 | eleventyConfig.setLibrary("md", markdown); 108 | eleventyConfig.addPlugin(syntaxHighlight); 109 | eleventyConfig.addPassthroughCopy("docs/*.css"); 110 | eleventyConfig.addPassthroughCopy("docs/assets/**/*"); 111 | return { 112 | dir: { 113 | input: "docs", 114 | output: "dist" 115 | } 116 | }; 117 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docs-and-guides", 3 | "version": "0.0.1", 4 | "description": "Web component documentation and guides", 5 | "type": "module", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "eleventy --serve", 9 | "build": "npm run clean && eleventy", 10 | "bump": "npm --no-git-tag-version version", 11 | "clean": "rimraf dist" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/webcomponents-cg/docs-and-guides.git" 16 | }, 17 | "keywords": [ 18 | "webcomponents", 19 | "docs", 20 | "howto", 21 | "guides" 22 | ], 23 | "contributors": [ 24 | { 25 | "name": "Thomas Allmer", 26 | "url": "https://github.com/daKmoR" 27 | }, 28 | { 29 | "name": "castastrophe", 30 | "url": "https://github.com/castastrophe" 31 | } 32 | ], 33 | "license": "MIT", 34 | "browserslist": [ 35 | "last 2 versions" 36 | ], 37 | "bugs": { 38 | "url": "https://github.com/webcomponents-cg/docs-and-guides/issues" 39 | }, 40 | "homepage": "https://github.com/webcomponents-cg/docs-and-guides#readme", 41 | "devDependencies": { 42 | "@11ty/eleventy": "^3.0.0", 43 | "@11ty/eleventy-plugin-syntaxhighlight": "^5.0.0", 44 | "markdown-it": "^14.1.0", 45 | "markdown-it-anchor": "^9.2.0", 46 | "rimraf": "^6.0.1" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /plan/README.md: -------------------------------------------------------------------------------- 1 | # Docs and Guide Plan 2 | 3 | This folder exists to capture the current docs plans in a central place where changes to the plans can be reviewed in PRs. 4 | 5 | [Outline](./outline.md) 6 | -------------------------------------------------------------------------------- /plan/outline.md: -------------------------------------------------------------------------------- 1 | # Docs Outline 2 | 3 | ## Overview 4 | 5 | This is an outline for the Docs section of the site, likely to be contained under the `/docs/` URL space. 6 | 7 | ### Goals 8 | 9 | The goals and contents of this section were discussed at the [Nov 17th WCCG meeting](https://docs.google.com/document/d/1uCQmHT_UTHtrf1xSfbQD5Ko23CpJrEY53wPIg3QHA5k/edit). 10 | 11 | The "docs" category of content is intended to be evrgreen conceptual and reference information that fits into a single hierarchical content outline. Docs should be mostly factual and objective, outside of the shared opinions of the community group on the benefits of web components in general. 12 | 13 | As a category, docs are distinct from articles and blog posts, which may be relevant for a point-in-time, have more opinions shared by only a subset of the WCCG, and/or be how-to's, tutorials and news. 14 | 15 | ### Docs MVP 16 | 17 | A [docs MVP](https://github.com/webcomponents-cg/docs-and-guides/issues/33) which could replace the current webcomponents.org includes: 18 | 19 | - [What are web components?](https://github.com/webcomponents-cg/docs-and-guides/issues/29) 20 | - [Why web components?](https://github.com/webcomponents-cg/docs-and-guides/issues/30) 21 | - [Related specifications](https://github.com/webcomponents-cg/docs-and-guides/issues/31) 22 | - [Web Component Libraries](https://github.com/webcomponents-cg/docs-and-guides/issues/32) 23 | 24 | ## Outline 25 | *
What are web components? 26 | 27 | * URL: `/docs/what-are-web-components` 28 | * Priority: P0 29 | * Issue: https://github.com/webcomponents-cg/docs-and-guides/issues/29 30 | * Page content: 31 | * Custom Elements 32 | * Shadow DOM 33 | * Standard JS Modules 34 | 35 |
36 | 37 | *
Why web components? 38 | 39 | * URL: `/docs/why-web-components` 40 | * Priority: P0 41 | * Issue: https://github.com/webcomponents-cg/docs-and-guides/issues/30 42 | * Page content: 43 | * What do we mean by interop? 44 | * Interop with HTML, frameworks, the browser 45 | * Interop with file formats: Markdown vs MDX, etc. 46 | * Interoperable composition with slots 47 | * Interop with the future 48 | * Use cases 49 | * Standalone components 50 | * Component sets and design systems 51 | * Applications 52 | * Who's using web components (Possibly separate page) 53 | 54 |
55 | 56 | *
Related specifications 57 | 58 | * URL: `/docs/specifications` or `/docs/standards` 59 | * Priority: P0 60 | * Issue: https://github.com/webcomponents-cg/docs-and-guides/issues/31 61 | * Page content: 62 | * MDN links 63 | * GitHub repos with proposals 64 | * What's left, ie. WCCG reports 65 | * Cross-link to site's Community Protocols page 66 | 67 |
68 | 69 | * Using web components 70 | *
Basics 71 | 72 | * URL: `/docs/using-web-components` or `/docs/using-web-components/basics` 73 | * Priority: P1 74 | * Issue: 75 | * Page content: 76 | * Importing definitions 77 | * Using web components in HTML and vanilla JS 78 | * Definining, the custom element registry, and the single tag name scope 79 | * Upgrading and `:defined` 80 | * Children and slots 81 | * Events 82 | 83 |
84 | 85 | *
Styling 86 | 87 | * URL: `/docs/using-web-components/styling` 88 | * Priority: P1 89 | * Issue: 90 | * Page content: 91 | * Shadow DOM encapsulation 92 | * CSS Custom Variables 93 | * ::part() 94 | * Attributes (for elements that use attributes for styling) 95 | 96 |
97 | 98 | *
Using web components with frameworks 99 | 100 | * URL: `/docs/using-web-components/frameworks` 101 | * Priority: P1 102 | * Issue: 103 | * Page content: 104 | * General considerations 105 | * Setting attributes and properties 106 | * Listening for events 107 | * Slots 108 | * Methods (and refs) 109 | * Template type-checking and linting 110 | * SSR 111 | * Examples in React, Angular, Vue 112 | 113 |
114 | 115 | *
Using web components with other tools 116 | 117 | * URL: `/docs/using-web-components/tools` 118 | * Priority: P1 119 | * Issue: 120 | * Page content: 121 | * Markdown (how to import in various systems) 122 | * Eleventy 123 | * Astro 124 | * Jekyl, Hugo... 125 | * CMSes: WordPress, Umbraco, Drupal, Laravel? 126 | 127 |
128 | 129 | *
Writing web components 130 | 131 | This section is about the concepts and APIs relevant to writing web components, which should apply to "vanilla" web components as well as most web component libraries. It is not a tutorial on writing vanilla web components. 132 | 133 |
134 | 135 | *
Defining custom elements 136 | 137 | * URL: `/docs/writing-web-components/defining` 138 | * Priority: P1 139 | * Issue: 140 | * Page content: 141 | * Custom element registries 142 | * Synchronous upgrade, and upgrade() 143 | * Self-registering vs not 144 | * Defensive registration for special cases (CDN distribution) 145 | 146 |
147 | 148 | *
Lifecycle 149 | 150 | * URL: `/docs/writing-web-components/lifecycle` 151 | * Priority: P1 152 | * Issue: 153 | * Page content: 154 | * Basics: `observedAttributes`, `constructor`, `attributeChangedCallback`... 155 | * Cleaning up resources in `disconnectedCallback` 156 | 157 |
158 | 159 | *
Shadow DOM 160 | 161 | * URL: `/docs/writing-web-components/shadow-dom` 162 | * Priority: P1 163 | * Issue: 164 | * Page content: 165 | * attachShadow() 166 | * open vs closed 167 | * Encapsulation: DOM, events, CSS 168 | * Just overview: more detail in Styling and Composition sections 169 | * Slots 170 | 171 |
172 | 173 | *
Styling 174 | 175 | * URL: `/docs/writing-web-components/styling` 176 | * Priority: P1 177 | * Issue: 178 | * Page content: 179 | * Encapsulation (more detail than) 180 | * Shadow selectors: `:host`, `:host()`, and `::slotted()` 181 | * CSS Custom Properties 182 | * CSS Shadow Parts: `part` and `::part()` 183 | * Constructible style sheets 184 | * Theming 185 | * Strategies for deep styling 186 | 187 |
188 | 189 | *
Dealing with data 190 | 191 | * URL: `/docs/writing-web-components/data` 192 | * Priority: P1 193 | * Issue: 194 | * Page content: 195 | * Designing both a property & attribute API 196 | * Responding to attribute changes (`attributeChangedCallback`) 197 | * Responding to property changes (accessors) 198 | * Considerations about when to use methods 199 | * Reflecting between properties and attributes 200 | * Using events for data 201 | 202 |
203 | 204 | *
Publishing to npm 205 | 206 | * URL: `/docs/writing-web-components/publishing` 207 | * Priority: P2 208 | * Issue: 209 | * Page content: 210 | 211 |
212 | 213 | *
Composition 214 | 215 | * URL: `/docs/writing-web-components/composition` 216 | * Priority: P2 217 | * Issue: 218 | * Page content: 219 | * Slots 220 | * Communicating with events 221 | * Using children 222 | 223 |
224 | 225 | *
Accessibility 226 | 227 | * URL: `/docs/writing-web-components/accessibility` 228 | * Priority: P1 229 | * Issue: 230 | * Page content: 231 | * Slots 232 | * Communicating with events 233 | * Using children 234 | 235 |
236 | 237 | 238 | *
Forms 239 | 240 | * URL: `/docs/writing-web-components/forms` 241 | * Priority: P2 242 | * Issue: 243 | * Page content: 244 | * Shadow DOM scoping and forms 245 | * Form-associated-custom-elements 246 | * formdata event 247 | 248 |
249 | 250 | *
Web component libraries 251 | 252 | * URL: `/docs/writing-web-components/libraries` 253 | * Priority: P0 254 | * Issue: https://github.com/webcomponents-cg/docs-and-guides/issues/32 255 | * Page content: 256 | * Links to client-side libraries 257 | 258 |
259 | 260 | *
Tools 261 | 262 | * URL: `/docs/writing-web-components/tools` 263 | * Priority: P2 264 | * Issue: 265 | * Page content: 266 | * Links to IDE extensions, linters, etc 267 | 268 |
269 | 270 | *
Community Protocols 271 | 272 | * URL: `/docs/community-protocols` 273 | * Priority: P2 274 | * Issue: 275 | * Page content: 276 | 277 |
278 | 279 | *
Community and Resources 280 | 281 | * URL: `/docs/resources` 282 | * Priority: P2 283 | * Issue: 284 | * Page content: 285 | * Links to chats, meetups, Twitter communities, etc. 286 | 287 |
288 | 289 | *
FAQ 290 | * URL: `/docs/faq` 291 | * Priority: P2 292 | * Issue: 293 | * Page content: 294 | * Myth-busting answers can go here 295 | * Can custom elements really only take strings? 296 | * Is it impossible to SSR web components? 297 | * Why don't web components solve ___ that other frameworks do? 298 | * ... 299 | 300 |
301 | --------------------------------------------------------------------------------