create-modulo
Version:
Starter projects for Modulo.html - Ready for all uses - Markdown-SSG / SSR / API-backed SPA
226 lines (175 loc) • 9.59 kB
HTML
<!DOCTYPE html><script src=../static/Modulo.html></script><script type=md>---
title: Style - Component Parts
---
# Style
The _Style_ Component Part allows us to write CSS for our component. This allows us to
group styles within our component, and keep them isolated from other
components, without having to come up with long, confusing class names every
time. CSS written here will be automatically prefixed so that it will only
apply to your component and/or any HTML that it generates, such as by the
_Template_ Component Part.
## General usage
In general, you can freely write any number of CSS rules for your components.
They will be prefixed based on a few regular expression replacement steps, such
that they only apply to the elements within your component. For example, a rule
like `a { color: blue }` in a component named `name="HelloBtn"` that has been
imported with `namespace="mylib"` would result in the following, fully-prefixed
rule: `mylib-HelloBtn a { color: blue }`
### Typical usage
```modulo
edit: demo=modulo
<Template>
Hello <strong>Modulo</strong> World!
<p class="neat">Any HTML can be here!</p>
</Template>
<Style>
/* ...and any CSS here! */
strong {
color: blue;
}
.neat {
font-variant: small-caps;
}
:host { /* styles the entire component */
display: inline-block;
background-color: cornsilk;
padding: 5px;
box-shadow: 10px 10px 0 0 turquoise;
}
</Style>
```
## Advanced usage
If you want to go deeper, you might customize it with specifying a
`url-replace` mode, or an `isolation-mode`.
### URL Replacement
By default (`url-replace:=true`), it will attempt to "fix" all relative URLs
into absolute URLs, either with the host specified or without, if (and only if)
you imported that _Style_ with a `-src=` attribute. To turn off this feature,
specify `url-replace:=false` on your _Style_ component.
#### URL replacement example
To see the `url-replace` feature in action, see below:
```modulo
edit: demo=modulo
<Template>
Hello <strong>Modulo</strong> World! <p class="neat">This
background works even when the CSS is bundled.</p>
</Template>
<!-- In sample.css, we have background: url('./example_image.jpg')
and its replaced with url('./example-data/example_image.jpg') -->
<Style
-src="example-data/sample.css"
></Style>
```
##### Without url-replace
To see why it's necessary, try disabling the `url-replace` feature and note how
the background no longer works (since it will use the relative URL given in the
image, which is then relative to this page, instead of the CSS file):
```modulo
<Style
url-replace:=false
-src="example-data/sample.css"
></Style>
```
-----
## Isolation
To keep CSS separate and easier to debug, Modulo _Style_ Component Parts
provide handy utilities to "isolates" whatever CSS you provide it.
### Isolation modes
The Style Component Part is capable of "isolating" it's contents using one of several
strategies: _Prefix isolation_ (using the "descendent" CSS selector), _Class
isolation- (where a class is attached to all matching elements generated by the
Component, and the `:is()` CSS selector is used to join the class with all
selectors in the Component), and finally _Shadow isolation_ (where the
browser's Shadow DOM is used to isolate the styles of this component).
#### Prefix isolation (default for `<Component ...`)
By default, components have "regular" rendering mode. This will cause it to
prefix like described above. That is, every selector in the CSS styles enclosed
will be prefixed with the name of the component.
For example, a rule like `div.alert { color: green }` in a component named
`name="HelloBtn"` that has been imported with `namespace="mylib"` would result
in the following, fully-prefixed rule: `mylib-HelloBtn a { color: green }`
#### Class isolation (`<Component mode="vanish"...`)
If you've configured your component to instead use "vanish" rendering, it will
to make the component function as basically a one-time template that "vanishes"
away after rendering, leaving only it's children. When this mode is set, the
Style Component Part will enable class-based isolation, where new classes are attached
to elements to isolate your CSS. This is one of the most precise techniques for
isolation - only affecting those elements that should be selected, while
leaving children untouched.
The technique for this is the most involved of the three isolation modes: It
will modify your resulting DOM to add a class to every referenced element. By
default, the class name chosen will be the same as the Component tag name.
Also, it will only add to elements that are referenced in your CSS. It will
ignore any non-targeted elements. However, as a warning, it can still end up
inflating your HTML size: E.g. if you have 100 paragraphs in a _Component_, all
of the 100 paragraphs will get the class.
Example: If there is a style like `p.quote strong`, in a component named
`mylib-HelloBtn`, then it will re-use the component name as a CSS class to the
which it adds to the `strong` element specified. Then it will use the `:is()`
CSS selector is used to join the class, resulting in the CSS of:
`.mylib-HelloBtn:is(p.quote strong)`
#### Shadow DOM isolation (`<Component mode="shadow"...`)
If you've configured your component to instead use "Shadow DOM" rendering to
protect it from getting outside CSS applied to it, then the _Style_ will be
"encapsulated" or inserted in the "shadow root" of component instances, as
opposed to the document root. (More on this here: [MDN's
"ShadowRoot.styleSheets"](https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot/styleSheets))
When using Shadow DOM, both the stylesheet and DOM will NOT be modified.
Instead, the CSS will automatically be isolated by nature of the browser's
shadow DOM CSS isolation feature. This isolates the component's DOM from the
parent's styles, causing guaranteed CSS isolation. Keep in mind, however, it
creates a new "open shadow root" DOM node, and prevents global styles (e.g.
regular link tags) from being applied. If you prefer using shadow DOM for
components, you can share base-style across shared Style components (browsers
should notice repeated duplicate shadow DOM sheet insertions and should be
optimized accordingly).
`div.alert { color: green }` in a component named `name="HelloBtn"` that has
been imported with `namespace="mylib"` would result in the following,
fully-prefixed rule: `mylib-HelloBtn a { color: green }`
`isolate-class` \- Force "isolate class" feature to be on, even if the
component is not in a vanish-based rendering mode. component itself. This will
work for both "regular" and "shadow" rendering mode. For example, in regular
rendering mode, if you have the CSS `:host { color: red }` in a component named
`name="MyChart"` that has been imported with `namespace="mylib"`, then it would
create the following, fully-prefixed CSS rule: `mylib-MyChart { color: red }`
`:host` \- Use the ":host" pseudo-element to select the component itself. This
will work for both "regular" and "shadow" rendering mode. For example, in
regular rendering mode, if you have the CSS `:host { color: red }` in a
component named `name="MyChart"` that has been imported with
`namespace="mylib"`, then it would create the following, fully-prefixed CSS
rule: `mylib-MyChart { color: red }`
### Overriding isolation mode
Isolation mode is auto-detected by default, based on the component mode.
However, the behavior can be overridden on a per-_Style_ basis by using the
`-auto-isolate` definition processor attribute.
## Configuring Style
Style components "try to do the right thing", by autodetecting their behavior
based on the Component configuration. However, sometimes it's necessary to
override the auto-detection. Also, features like prefix-isolation are very
useful in many web tasks while integrating legacy sites.
- `prefix` - Used to specify prefix-based isolation.
- `prefix="#chart_styles" - Prefix every selector in a CSS style sheet with
`#chart_styles`, to keep it "isolated" within the HTML element with
`id="chart_styles`.
- `-auto-isolate` - Set this to one of the component modes to override
autodetection and force that behavior. The default value is `true`, which
will autodetect based on the component mode as described above.
- Example: Set this to `-auto-isolate="vanish"` to force vanish-style
isolation on a non-vanishing component
- Example: Set this to `-auto-isolate:=false` to totally turn off isolation.
- `isolate-class` - Enables class-based isolation. You can use this property
to override the class used as well.
- Example: Set this to `isolate-class="my-component"` to create a
`.my-component` class to get added to all CSS selectors and relevant DOM
elements
- `isolate-selector` - Not typically useful, but this enables you to specify
which elements you want to select with the `isolate-class specified. By
default, it will only be elements that are specified in CSS, but this is your
chance to override that default behavior.
- Example: `isolate-selector="p,div"` will only attempt to isolate `p`
and `div` tags if/when an `isolate-class` is used
- `url-replace` - By default (`url-replace:=true`), it will attempt to "fix"
all relative URLs into absolute URLs, either with the host specified or
without, if (and only if) you imported that _Style_ with a `-src=` attribute.
To turn off this feature, specify `url-replace:=false` on your _Style_
component.