search
HomeWeb Front-endCSS TutorialIntroducing Shoelace, a Framework-Independent Component-Based UX Library

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>

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;

…and bind it:

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

Now we can add a button to call it:

<button on:click="{()"> tabs.show("custom")}>Show custom</button>
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>

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>

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;

Finally, let's connect our Open dialog button:

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

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>
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>

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
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
How We Tagged Google Fonts and Created goofonts.comHow We Tagged Google Fonts and Created goofonts.comApr 12, 2025 pm 12:02 PM

GooFonts is a side project signed by a developer-wife and a designer-husband, both of them big fans of typography. We’ve been tagging Google

Timeless Web Dev ArticlesTimeless Web Dev ArticlesApr 12, 2025 am 11:44 AM

Pavithra Kodmad asked people for recommendations on what they thought were some of the most timeless articles about web development that have changed their

The Deal with the Section ElementThe Deal with the Section ElementApr 12, 2025 am 11:39 AM

Two articles published the exact same day:

Practice GraphQL Queries With the State of JavaScript APIPractice GraphQL Queries With the State of JavaScript APIApr 12, 2025 am 11:33 AM

Learning how to build GraphQL APIs can be quite challenging. But you can learn how to use GraphQL APIs in 10 minutes! And it so happens I've got the perfect

Component-Level CMSsComponent-Level CMSsApr 12, 2025 am 11:09 AM

When a component lives in an environment where the data queries populating it live nearby, there is a pretty direct line between the visual component and the

Set Type on a Circle... with offset-pathSet Type on a Circle... with offset-pathApr 12, 2025 am 11:00 AM

Here's some legit CSS trickery from yuanchuan. There is this CSS property offset-path. Once upon a time, it was called motion-path and then it was renamed. I

What does 'revert' do in CSS?What does 'revert' do in CSS?Apr 12, 2025 am 10:59 AM

Miriam Suzanne explains in a Mozilla Developer video on the subject.

The Modern LoversThe Modern LoversApr 12, 2025 am 10:58 AM

I love stuff like this.

See all articles

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 agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: How To Unlock Everything In MyRise
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Integrate Eclipse with SAP NetWeaver application server.

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

Dreamweaver Mac version

Dreamweaver Mac version

Visual web development tools

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.