Table of Contents
Since I want this post to focus on Shoelace and its web component features, I will use Svelte for everything. I will also use this Stackblitz project for demonstration. We will build this demo step by step together, but you can open REPL at any time to see the final result.
Shoelace introduction
Interact with API: Methods and Events
Tags
Dialogue
Customize all styles!
View one of the tag titles in your DevTools; it should look like this:
A classic and more frustrating problem in web development has always been style cascading where we don't want them to appear. You may be worried that any style rules in the application that specify something like
attribute is inheritable, try setting a new value, such as
attribute. Let's use these facts to locate the active tag and change the cursor:
Custom animation
Summary
Home Web Front-end CSS Tutorial Introducing Shoelace, a Framework-Independent Component-Based UX Library

Introducing Shoelace, a Framework-Independent Component-Based UX Library

Mar 10, 2025 am 10:46 AM

Introducing Shoelace, a Framework-Independent Component-Based UX Library

This article introduces Shoelace, a component library created by Cory LaViska, but it is unique. It defines all standard UX components: tags, modal boxes, accordion, autocomplete, and more. These components are out of the box, beautiful, easy to use, and completely customizable. But it does not create these components using frameworks like React, Solid, or Svelte, but uses Web Components; this means you can use them with any framework.

Preparation

Web Components are great, but there are still some minor issues to pay attention to at the moment.

React

I've said before that they can be used in any JavaScript framework, but I've also written before that React's support for Web Components is currently poor. To solve this problem, Shoelace created wrappers specifically for React.

Another option I personally prefer is to create a lightweight React component that accepts the web component's tag name and all its properties, and then deal with the shortcomings of React. I discussed this option in a previous post. I like this scheme because it is designed to be removed. React's experimental branch has solved the problem of web component interoperability so once published, any lightweight web component interoperability component used can be searched and removed, leaving behind direct web component usage without any React wrappers.

Server-side Rendering (SSR)

As of this writing, support for SSR is also poor. In theory, there is a technique called declarative Shadow DOM (DSD) that can implement SSR. But browser support is limited, and DSD actually requires

server support to work properly, meaning Next, Remix, or any other tool you use on the server will need some special processing power. That is, there are other ways to make Web Components "work properly" with web applications that use tools such as Next for SSR. In short, a script that registers Web Components needs to be run in a blocking script before parsing the tag. But this will be the subject of another post.

Of course, if you are building any type of client rendering SPA, this is not a problem. This is what we will use in this post.

Start

Since I want this post to focus on Shoelace and its web component features, I will use Svelte for everything. I will also use this Stackblitz project for demonstration. We will build this demo step by step together, but you can open REPL at any time to see the final result.

I will show you how to use Shoelace and, more importantly, how to customize it. We'll discuss Shadow DOM and what external styles they block (and which styles are not blocked). We'll also discuss the

CSS selector – which may be brand new to you – we'll even see how Shoelace allows us to overwrite and customize its various animations.

If you find yourself enjoying Shoelace after reading this article and want to try it in your React project, my suggestion is to use the wrapper mentioned in my introduction. This will allow you to use any component of Shoelace and you can remove it completely once React releases the web component fix they already have (find in version 19).

Shoelace introduction

Shoelace has quite detailed installation instructions. The easiest way is to add the <script></script> and <link> tags to your HTML document, and that's it. However, for any production application, you may just want to selectively import what you want, and there are instructions accordingly as well.

After installing Shoelace, let's create a Svelte component to render some content, and then go through the steps of fully customizing it. To select some more complex content, I used the tags and dialogs (often called modal boxes) components. Here are some tags that mainly come from the documentation:

<sl-tab-group>
  <sl-tab panel="general" slot="nav">General</sl-tab>
  <sl-tab panel="custom" slot="nav">Custom</sl-tab>
  <sl-tab panel="advanced" slot="nav">Advanced</sl-tab>
  <sl-tab disabled panel="disabled" slot="nav">Disabled</sl-tab>
  <sl-tab-panel name="general">This is the general tab panel.</sl-tab-panel>
  <sl-tab-panel name="custom">This is the custom tab panel.</sl-tab-panel>
  <sl-tab-panel name="advanced">This is the advanced tab panel.</sl-tab-panel>
  <sl-tab-panel name="disabled">This is a disabled tab panel.</sl-tab-panel>
</sl-tab-group>
<sl-dialog label="Dialog" no-header="">
  Hello World!
  <sl-button> open = false}>Close</sl-button>
</sl-dialog>
<br><br>
<button> open = true}>Open Dialog</button>
Copy after login
Copy after login
Copy after login
Copy after login

This will present some beautiful and styled labels. The underscore of the activity tag even animates well and slides from one activity tag to the next.

I won't waste your time detailing each API that has been documented in detail on the Shoelace website. Instead, let's look at how best to interact and fully customize these Web Components.

Interact with API: Methods and Events

Calling methods and subscription events on web components may be slightly different from the normal framework you are used to, but this is not too complicated. Let's see how to do it.

Tags

The

Tag component (<sl-tab-group></sl-tab-group>) has a show method that displays a specific tag manually. In order to call it, we need to access the underlying DOM element of the tag. In Svelte, this means using bind:this. In React, it will be a ref. etc. Since we are using Svelte, let's declare a tag instance variable:

let tabs;
Copy after login
Copy after login

…and bind it:

<sl-tab-group bind:this="{tabs}"></sl-tab-group>
Copy after login
Copy after login

Now we can add a button to call it:

<button on:click="{()"> tabs.show("custom")}>Show custom</button>
Copy after login
The same is true for the

Events. When a new tag is displayed, a sl-tab-show event is triggered. We can use tabs for our addEventListener variable, or we can use Svelte's on:event-name shortcut.

<sl-tab-group bind:this="{tabs}" on:sl-tab-show="{e"> console.log(e)}></sl-tab-group>
Copy after login

This works and logs event objects when different tags are displayed.

Usually we render the tags and let the user click between them, so this work is usually not even needed, but if you need it, it's there. Now let's make the dialog components interactive.

Dialogue

The

dialog component (<sl-dialog></sl-dialog>) accepts a open attribute that controls whether the dialog box... is open. Let's declare it in our Svelte component:

<sl-tab-group>
  <sl-tab panel="general" slot="nav">General</sl-tab>
  <sl-tab panel="custom" slot="nav">Custom</sl-tab>
  <sl-tab panel="advanced" slot="nav">Advanced</sl-tab>
  <sl-tab disabled panel="disabled" slot="nav">Disabled</sl-tab>
  <sl-tab-panel name="general">This is the general tab panel.</sl-tab-panel>
  <sl-tab-panel name="custom">This is the custom tab panel.</sl-tab-panel>
  <sl-tab-panel name="advanced">This is the advanced tab panel.</sl-tab-panel>
  <sl-tab-panel name="disabled">This is a disabled tab panel.</sl-tab-panel>
</sl-tab-group>
<sl-dialog label="Dialog" no-header="">
  Hello World!
  <sl-button> open = false}>Close</sl-button>
</sl-dialog>
<br><br>
<button> open = true}>Open Dialog</button>
Copy after login
Copy after login
Copy after login
Copy after login

It also has a sl-hide event for hiding the dialog box. Let's pass our open property and bind to the hidden event so that when the user clicks to close it outside the dialog content, we can reset it. Let's add a click handler to that close button to set our open property to false, which will also close the dialog.

let tabs;
Copy after login
Copy after login

Finally, let's connect our Open dialog button:

<sl-tab-group bind:this="{tabs}"></sl-tab-group>
Copy after login
Copy after login

That's it. Interaction with the component library's API is more or less direct. If this article only does this, it would be quite boring.

But Shoelace - built with Web Components - means that something, especially styles, works slightly differently than what we are used to.

Customize all styles!

At the time of writing, Shoelace is still in beta, and the creators are considering changing some default styles, and maybe even removing some default styles altogether so they don't overwrite the styles of the host application anymore. The concepts we will introduce are relevant anyway, but don't be surprised if some of the Shoelace details I mentioned differ when you use it.

Shoelace's default style is good, but our web application may also have its own design and hope our UX components match it. Let's see how to do this in the world of Web Components.

We are not trying to actually improve anything. The creator of Shoelace is better at design than I do. Instead, we just look at how to change stuff so you can adapt to your own web application. Quick View Shadow DOM

View one of the tag titles in your DevTools; it should look like this:

Our tag element creates a div container with

and

classes and a .tab, while also displaying the text we entered for that tag. But please note that it is located within .tab--activeshadow roottabindex. This allows web component authors to add their own tags to web components, while also providing a place to place what we provide. Pay attention to the elements? This basically means "put whatever the user renders between web component tags in here <slot></slot>". So the

component creates a shadow root, adding something to it to render a nice-style label title as well as a placeholder (

) where it renders our content. <sl-tab></sl-tab> <slot></slot>Packaging Style

A classic and more frustrating problem in web development has always been style cascading where we don't want them to appear. You may be worried that any style rules in the application that specify something like

will interfere with these tags. It turns out that this is not a problem; shadow roots encapsulate the style. The style outside the shadow root does not affect what is inside the shadow root (with some exceptions, which we will discuss later), and vice versa.

Exception to this is an inheritable style. Of course, you don't need to apply font-family styles for every element in your web application. Instead, you can specify your :root or html last time and let it inherit everything under it. This inheritance will actually penetrate shadow root. font-family

CSS custom properties (commonly called "css variables") are a related exception. Shadow root can definitely read CSS properties defined outside of shadow root; this will become relevant later.

Selector::part

What about the styles that are not inherited? If we want to customize something inside the shadow root (such as

that does not inherit), are we unlucky? It turns out we didn't. Check out the above label element image and its shadow root again. Pay attention to the attribute on the div? This allows you to locate and style the element from outside the shadow root using the selector. We will introduce an example step by step. cursor partOverwrite Shoelace style::part

Let's see the practical application of these methods. As of now, many Shoelace styles (including fonts) receive default values ​​from CSS custom properties. To align these fonts with the application's style, override the relevant custom properties. See the documentation for which CSS variables Shoelace is using, or you can simply check the styles in any given element in DevTools.

Inherit styles through shadow root

Open the app.css file in the src directory of the StackBlitz project. In the section at the bottom, you should see a

statement. Since the

attribute is inheritable, try setting a new value, such as

. After saving, all content (including the tag title defined in shadow root) will be adjusted accordingly.

:rootOverwrite Shoelace CSS variablesletter-spacing: normal; The letter-spacing2px component reads a

CSS custom property for underscores of active tags. We can use some basic CSS to override it:

That's it, we now have the green indicator! <sl-tab-group></sl-tab-group> --indicator-colorInquiry Parts

<sl-tab-group>
  <sl-tab panel="general" slot="nav">General</sl-tab>
  <sl-tab panel="custom" slot="nav">Custom</sl-tab>
  <sl-tab panel="advanced" slot="nav">Advanced</sl-tab>
  <sl-tab disabled panel="disabled" slot="nav">Disabled</sl-tab>
  <sl-tab-panel name="general">This is the general tab panel.</sl-tab-panel>
  <sl-tab-panel name="custom">This is the custom tab panel.</sl-tab-panel>
  <sl-tab-panel name="advanced">This is the advanced tab panel.</sl-tab-panel>
  <sl-tab-panel name="disabled">This is a disabled tab panel.</sl-tab-panel>
</sl-tab-group>
<sl-dialog label="Dialog" no-header="">
  Hello World!
  <sl-button> open = false}>Close</sl-button>
</sl-dialog>
<br><br>
<button> open = true}>Open Dialog</button>
Copy after login
Copy after login
Copy after login
Copy after login
In the Shoelace version I am currently using (2.0.0-beta.83), any non-disabled tag has a pointer cursor. Let's change it to the default cursor for the active (selected) tag. We have seen the

element add a

attribute on the container of the tag title. Additionally, the currently selected tag receives a

attribute. Let's use these facts to locate the active tag and change the cursor:

<sl-tab></sl-tab>That's it! part="base"

Custom animation

To add icing on the cake, let's see how Shoelace allows us to customize animations. Shoelace uses the Web Animations API and exposes a setDefaultAnimation API to control how different elements animate their various interactions. See the documentation for more information, but for example, here is how to change Shoelace's default dialog animation from expanding out and shrinking inward to entering from the top animation and moving downward when hidden.

<sl-tab-group>
  <sl-tab panel="general" slot="nav">General</sl-tab>
  <sl-tab panel="custom" slot="nav">Custom</sl-tab>
  <sl-tab panel="advanced" slot="nav">Advanced</sl-tab>
  <sl-tab disabled panel="disabled" slot="nav">Disabled</sl-tab>
  <sl-tab-panel name="general">This is the general tab panel.</sl-tab-panel>
  <sl-tab-panel name="custom">This is the custom tab panel.</sl-tab-panel>
  <sl-tab-panel name="advanced">This is the advanced tab panel.</sl-tab-panel>
  <sl-tab-panel name="disabled">This is a disabled tab panel.</sl-tab-panel>
</sl-tab-group>
<sl-dialog label="Dialog" no-header="">
  Hello World!
  <sl-button> open = false}>Close</sl-button>
</sl-dialog>
<br><br>
<button> open = true}>Open Dialog</button>
Copy after login
Copy after login
Copy after login
Copy after login

This code is located in the App.svelte file. Comment out it to see the original default animation.

Summary

Shoelace is a very ambitious component library built using Web Components. Since Web Components are framework-free, they can be used with any framework for any project. As new frameworks begin to show amazing performance features and ease of use, being able to use quality user experience components that are not bound by either framework is more attractive than ever.

The above is the detailed content of Introducing Shoelace, a Framework-Independent Component-Based UX Library. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: How To Unlock Everything In MyRise
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Working With GraphQL Caching Working With GraphQL Caching Mar 19, 2025 am 09:36 AM

If you’ve recently started working with GraphQL, or reviewed its pros and cons, you’ve no doubt heard things like “GraphQL doesn’t support caching” or

Making Your First Custom Svelte Transition Making Your First Custom Svelte Transition Mar 15, 2025 am 11:08 AM

The Svelte transition API provides a way to animate components when they enter or leave the document, including custom Svelte transitions.

Show, Don't Tell Show, Don't Tell Mar 16, 2025 am 11:49 AM

How much time do you spend designing the content presentation for your websites? When you write a new blog post or create a new page, are you thinking about

Building an Ethereum app using Redwood.js and Fauna Building an Ethereum app using Redwood.js and Fauna Mar 28, 2025 am 09:18 AM

With the recent climb of Bitcoin’s price over 20k $USD, and to it recently breaking 30k, I thought it’s worth taking a deep dive back into creating Ethereum

How do you use CSS to create text effects, such as text shadows and gradients? How do you use CSS to create text effects, such as text shadows and gradients? Mar 14, 2025 am 11:10 AM

The article discusses using CSS for text effects like shadows and gradients, optimizing them for performance, and enhancing user experience. It also lists resources for beginners.(159 characters)

Creating Your Own Bragdoc With Eleventy Creating Your Own Bragdoc With Eleventy Mar 18, 2025 am 11:23 AM

No matter what stage you’re at as a developer, the tasks we complete—whether big or small—make a huge impact in our personal and professional growth.

What the Heck Are npm Commands? What the Heck Are npm Commands? Mar 15, 2025 am 11:36 AM

npm commands run various tasks for you, either as a one-off or a continuously running process for things like starting a server or compiling code.

Let's use (X, X, X, X) for talking about specificity Let's use (X, X, X, X) for talking about specificity Mar 24, 2025 am 10:37 AM

I was just chatting with Eric Meyer the other day and I remembered an Eric Meyer story from my formative years. I wrote a blog post about CSS specificity, and

See all articles