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
What is CSS Grid?What is CSS Grid?Apr 30, 2025 pm 03:21 PM

CSS Grid is a powerful tool for creating complex, responsive web layouts. It simplifies design, improves accessibility, and offers more control than older methods.

What is CSS flexbox?What is CSS flexbox?Apr 30, 2025 pm 03:20 PM

Article discusses CSS Flexbox, a layout method for efficient alignment and distribution of space in responsive designs. It explains Flexbox usage, compares it with CSS Grid, and details browser support.

How can we make our website responsive using CSS?How can we make our website responsive using CSS?Apr 30, 2025 pm 03:19 PM

The article discusses techniques for creating responsive websites using CSS, including viewport meta tags, flexible grids, fluid media, media queries, and relative units. It also covers using CSS Grid and Flexbox together and recommends CSS framework

What does the CSS box-sizing property do?What does the CSS box-sizing property do?Apr 30, 2025 pm 03:18 PM

The article discusses the CSS box-sizing property, which controls how element dimensions are calculated. It explains values like content-box, border-box, and padding-box, and their impact on layout design and form alignment.

How can we animate using CSS?How can we animate using CSS?Apr 30, 2025 pm 03:17 PM

Article discusses creating animations using CSS, key properties, and combining with JavaScript. Main issue is browser compatibility.

Can we add 3D transformations to our project using CSS?Can we add 3D transformations to our project using CSS?Apr 30, 2025 pm 03:16 PM

Article discusses using CSS for 3D transformations, key properties, browser compatibility, and performance considerations for web projects.(Character count: 159)

How can we add gradients in CSS?How can we add gradients in CSS?Apr 30, 2025 pm 03:15 PM

The article discusses using CSS gradients (linear, radial, repeating) to enhance website visuals, adding depth, focus, and modern aesthetics.

What are pseudo-elements in CSS?What are pseudo-elements in CSS?Apr 30, 2025 pm 03:14 PM

Article discusses pseudo-elements in CSS, their use in enhancing HTML styling, and differences from pseudo-classes. Provides practical examples.

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

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Dreamweaver Mac version

Dreamweaver Mac version

Visual web development tools

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

Atom editor mac version download

Atom editor mac version download

The most popular open source editor

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.