Skip to content

Commit 9729d57

Browse files
author
R. S. Doiel
committed
Quick Save
1 parent edb0675 commit 9729d57

17 files changed

+301
-24
lines changed

DEVELOPERS.html

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,10 @@
1919
</nav>
2020
<section>
2121
<h1 id="developer-notes">Developer Notes</h1>
22-
<p>This is a new endevour for Caltech Library. Our practices are
23-
evolving as we devlop this project and we periodically make course
22+
<p>This is a new endeavor for Caltech Library. Our practices are
23+
evolving as we develop this project and we periodically make course
2424
corrections. In I hope to highlight approaches or technique that proved
2525
useful.</p>
26-
<h2 id="heuristics">Heuristics</h2>
27-
<ul>
28-
<li>this project is focused on web components useful to Libraries,
29-
Archives and Museums</li>
30-
<li>when a component extends a standard HTML element the standard
31-
element name should be used as a prefix,
32-
e.g. <code>&lt;textarea-agent-list&gt;</code>,
33-
<code>&lt;ul-a-to-z-list&gt;</code></li>
34-
</ul>
3526
</section>
3627
</body>
3728
</html>

DEVELOPERS.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11

22
# Developer Notes
33

4-
This is a new endevour for Caltech Library. Our practices are evolving as we devlop this project and we periodically make course corrections. In I hope to highlight approaches or technique that proved useful.
4+
This is a new endeavor for Caltech Library. Our practices are evolving as we develop this project. You should expected periodically make course corrections. The following documentation will highlight our approaches and techiniquess to solving the challenges of developing a web component library for libraries, archives and museums.
55

6-
## Heuristics
7-
8-
- this project is focused on web components useful to Libraries, Archives and Museums
9-
- when a component extends a standard HTML element the standard element name should be used as a prefix, e.g. `<textarea-agent-list>`, `<ul-a-to-z-list>`
6+
- [Web Component Naming](web_component_naming.md)
7+
- [Integrating CSS in Web Compnoents](integrating_css_in_web_components.md)

codemeta.json

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@
99
"givenName": "R. S.",
1010
"familyName": "Doiel",
1111
"email": "[email protected]"
12+
},
13+
{
14+
"type": "Person",
15+
"givenName": "Twila",
16+
"familyName": "Smith",
17+
"email": "[email protected]"
1218
}
1319
],
1420
"maintainer": [
@@ -21,7 +27,7 @@
2127
}
2228
],
2329
"dateCreated": "2025-02-26",
24-
"dateModified": "2025-07-07",
30+
"dateModified": "2025-07-17",
2531
"datePublished": "2025-07-07",
2632
"description": "CL-web-components provides a collection of Web Components used by Caltech Library in various web sites and projects.\n\nThe following are the components currently provided.\n\n\n`ul-a-to-z`\n: This component takes an innerHTML containing a UL list. The UL list is then turned into an A to Z navigatable UL List. If JavaScript is unavailable then the innerHTML UL remains as a fallback.\n\n`textarea-csv`\n: This is a textarea like component who's innerHTML content is CSV data. The component will display this as an editable table. \n\n`textarea-agent-list`\n: This element wraps a textarea containing a list of agents expressed as JSON. \n\n`table-sortable`\n: This is a component that takes an innerHTML containing table. It makes the table sortable by the column headings and provides a filter input that lets you enter text to filter by and pick a column to filter on.",
2733
"funder": [
@@ -46,16 +52,18 @@
4652
"https://github.com/caltechlibrary/a_to_z_ul"
4753
],
4854
"runtimePlatform": "HTML5-compatible web browser",
55+
"softwareRequirements": [
56+
"Deno >= 2.4.1 (for bundling dependencies)"
57+
],
4958
"softwareSuggestions": [
50-
"Deno >= 2.4",
51-
"CMTools >= 0.0.33",
59+
"CMTools >= 0.0.35",
5260
"Pandoc >= 3.1"
5361
],
54-
"version": "0.0.11",
62+
"version": "0.0.12",
5563
"developmentStatus": "wip",
5664
"issueTracker": "https://github.com/caltechlibrary/CL-web-components/issues",
5765
"downloadUrl": "https://github.com/caltechlibrary/CL-web-components/releases",
58-
"releaseNotes": "Renamed components to use a prefix of the standard element name they are extending.",
66+
"releaseNotes": "Updated documentation, preparation for integrating into Caltech Library design system. Improving CSV support in `textarea-csv` component.",
5967
"copyrightYear": 2025,
6068
"copyrightHolder": "California Institute of Technology"
6169
}
Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
2+
# Web Component CSS Implementation
3+
4+
One challenge and feature of web components is that they ecapsulate the component as a single HTML element. This is a design feature of web components that insure safe default behaviors. If the web component itself contains HTML elements the isolation maybe important for component rendering and behavior. On the otherhand if the web component itself contains standard HTML elements and they should inherit form the page level style sheet you have a problem. The safety of an encampulated component because a barrier to how we traditionally expect CSS to apply.
5+
6+
Adding inheritance inside the web component should be weighed carefully. If it is desirable to inherit an external CSS ruleset you have several options. First is to include the refererence as an import in the HTML template for the object. This is useful where the component will be used in a design system and the design system specifies the required CSS files and their locations.
7+
8+
Another approach is to passing in styling or stylesheet references via the web component's attributes. This can be done by defining the attributes `style` and `css-href` (or something similar). Having the `style` attributes the practice used generally with standard HTML elements. The style passed in can be vetted to make senses in the context of the whole component's rendering. A use case that fits this approach is here you might want the color scheme or front choice to pass through to the component. The `css-href` approach is slightly more complex. Before the HTML template text is instanciated you need to include the references to the CSS being included. It remains unclear if the web component can take advantage of the page's own CSS cache or if it will require an additional explicit download of the CSS. This area needs to exploration and testing to confirm behaviors.
9+
10+
All the approaches are reasonable assuming the trade offs and limitations are understood.
11+
12+
## Master stylesheet appoach
13+
14+
Here's are some use case examples of in corporating a master stylesheet approach (explitily include an `@import` rule in the component's style element).
15+
16+
### CSS Custom Properties (Variables)
17+
18+
Use CSS custom properties (also known as CSS variables) in your master CSS file. These variables can be defined globally and accessed within your web components.
19+
20+
~~~CSS
21+
/* master.css */
22+
:root {
23+
--primary-color: #4285f4;
24+
--secondary-color: #34a853;
25+
--font-family: 'Roboto', sans-serif;
26+
}
27+
~~~
28+
29+
In your web component, you can use these variables:
30+
31+
~~~CSS
32+
/* Inside your web component's styles */
33+
.my-element {
34+
color: var(--primary-color);
35+
font-family: var(--font-family);
36+
}
37+
~~~
38+
39+
### External Stylesheets in Shadow DOM:
40+
41+
You can include external stylesheets within your Shadow DOM by using JavaScript to clone the styles and append them to the Shadow DOM.
42+
43+
~~~JavaScript
44+
const template = document.createElement('template');
45+
template.innerHTML = `
46+
<style>
47+
@import url('master.css');
48+
</style>
49+
<div class="my-element">Styled content</div>
50+
`;
51+
52+
class MyElement extends HTMLElement {
53+
constructor() {
54+
super();
55+
this.attachShadow({ mode: 'open' }).appendChild(template.content.cloneNode(true));
56+
}
57+
}
58+
59+
customElements.define('my-element', MyElement);
60+
~~~
61+
62+
### Constructable Stylesheets:
63+
64+
Use Constructable Stylesheets to share styles across multiple shadow roots. This allows you to define styles once and use them in multiple components.
65+
66+
~~~JavaScript
67+
const sheet = new CSSStyleSheet();
68+
sheet.replaceSync(`
69+
.my-element {
70+
color: var(--primary-color);
71+
}
72+
`);
73+
74+
class MyElement extends HTMLElement {
75+
constructor() {
76+
super();
77+
this.attachShadow({ mode: 'open' });
78+
this.shadowRoot.adoptedStyleSheets = [sheet];
79+
}
80+
}
81+
82+
customElements.define('my-element', MyElement);
83+
~~~
84+
85+
### CSS Inheritance:
86+
87+
Some CSS properties are inherited by default (e.g., font-family, color). You can leverage these properties to style your web components without piercing the Shadow DOM.
88+
89+
~~~CSS
90+
/* master.css */
91+
body {
92+
font-family: var(--font-family);
93+
color: var(--primary-color);
94+
}
95+
~~~
96+
97+
These styles will be inherited by the elements inside your web component unless explicitly overridden.
98+
99+
#### `::part` and `::theme:`
100+
101+
Use the `::part` and `::theme` pseudo-elements to style specific parts of your web components from outside the Shadow DOM.
102+
103+
~~~CSS
104+
/* master.css */
105+
my-element::part(button) {
106+
background-color: var(--primary-color);
107+
}
108+
~~~
109+
110+
#### In your web component:
111+
112+
~~~HTML
113+
<button part="button">Click me</button>
114+
~~~
115+
116+
By using these strategies, you can effectively integrate a master CSS file with your web components while respecting the encapsulation provided by the Shadow DOM.
117+
118+
119+
## Configurable CSS via component attributes
120+
121+
You can conditionally include CSS and supply default styles for web components. This can be achieved through a combination of JavaScript logic and CSS management. Here are some strategies to accomplish this:
122+
123+
### Dynamic Stylesheet Loading:
124+
125+
You can use JavaScript to dynamically load stylesheets based on certain conditions. This allows you to include different stylesheets depending on the context or user preferences.
126+
127+
~~~JavaScript
128+
function loadStylesheet(href, id) {
129+
const link = document.createElement('link');
130+
link.rel = 'stylesheet';
131+
link.href = href;
132+
link.id = id;
133+
document.head.appendChild(link);
134+
}
135+
136+
// Conditionally load stylesheet
137+
if (someCondition) {
138+
loadStylesheet('special-styles.css', 'special-styles');
139+
} else {
140+
loadStylesheet('default-styles.css', 'default-styles');
141+
}
142+
~~~
143+
144+
### Inline Default Styles:
145+
146+
Provide default styles inline within your web component. You can then override these styles by conditionally loading external stylesheets.
147+
148+
~~~JavaScript
149+
const template = document.createElement('template');
150+
template.innerHTML = `
151+
<style>
152+
/* Default styles */
153+
.my-element {
154+
color: black;
155+
font-family: Arial, sans-serif;
156+
}
157+
</style>
158+
<div class="my-element">Styled content</div>
159+
`;
160+
161+
class MyElement extends HTMLElement {
162+
constructor() {
163+
super();
164+
this.attachShadow({ mode: 'open' }).appendChild(template.content.cloneNode(true));
165+
}
166+
167+
connectedCallback() {
168+
// Conditionally load external stylesheet
169+
if (this.hasAttribute('special')) {
170+
const link = document.createElement('link');
171+
link.rel = 'stylesheet';
172+
link.href = 'special-styles.css';
173+
this.shadowRoot.appendChild(link);
174+
}
175+
}
176+
}
177+
178+
customElements.define('my-element', MyElement);
179+
~~~
180+
181+
### CSS Custom Properties with Fallbacks:
182+
183+
Use CSS custom properties with fallback values to provide default styles. You can then conditionally override these properties.
184+
185+
~~~CSS
186+
/* Default styles using CSS custom properties with fallbacks */
187+
.my-element {
188+
color: var(--my-element-color, black);
189+
font-family: var(--my-element-font, Arial, sans-serif);
190+
}
191+
~~~
192+
193+
~~~JavaScript
194+
// Conditionally override CSS custom properties
195+
if (someCondition) {
196+
document.documentElement.style.setProperty('--my-element-color', 'blue');
197+
document.documentElement.style.setProperty('--my-element-font', 'Helvetica, sans-serif');
198+
}
199+
~~~
200+
201+
### Using JavaScript to Toggle Classes:
202+
203+
Apply different classes to your web component based on conditions and define styles for these classes in your CSS.
204+
205+
~~~JavaScript
206+
class MyElement extends HTMLElement {
207+
constructor() {
208+
super();
209+
this.attachShadow({ mode: 'open' });
210+
this.shadowRoot.innerHTML = `
211+
<style>
212+
.default-style {
213+
color: black;
214+
font-family: Arial, sans-serif;
215+
}
216+
.special-style {
217+
color: blue;
218+
font-family: Helvetica, sans-serif;
219+
}
220+
</style>
221+
<div class="my-element">Styled content</div>
222+
`;
223+
}
224+
225+
connectedCallback() {
226+
const element = this.shadowRoot.querySelector('.my-element');
227+
if (this.hasAttribute('special')) {
228+
element.classList.add('special-style');
229+
} else {
230+
element.classList.add('default-style');
231+
}
232+
}
233+
}
234+
235+
customElements.define('my-element', MyElement);
236+
~~~
237+
238+
By using these techniques, you can conditionally include CSS and supply default styles for your web components, making them more flexible and adaptable to different contexts and user preferences.
239+
478 Bytes
Binary file not shown.
498 Bytes
Binary file not shown.
943 Bytes
Binary file not shown.
4.19 KB
Binary file not shown.
303 Bytes
Binary file not shown.
14.1 KB
Binary file not shown.

0 commit comments

Comments
 (0)