What is the reason behind Svelte not scoping the tag under a class, but instead using individual tag.class to style a component?

It is common practice to scope CSS styles for components like this:

.my-component-01 h1 { ... }
.my-component-01 h2 { ... }

However, Svelte takes a different approach by applying the styles directly to the tags:

h1.svelte-hlsza1{color:orange}
h2.svelte-hlsza1{background:yellow}

Would it be better to actually wrap these styles under a specific class (the top method)? This way, in the HTML markup, you would only need to include the class once:

<div class="svelte-hlsza1">
  <h1> ...
  <h2> ...

This approach eliminates the need to repeat the class name every time and maintains the same level of specificity: 1 class and 1 tag name.

Answer №1

One of the unique features of Svelte is that it does not necessitate a single top-level element.

<!-- This is perfectly fine with Svelte -->
<h1>...</h1>
<h2>...</h2>

In fact, it doesn't even require elements at all.

<script>...</script>
<!-- Even without elements, Svelte still works smoothly -->

Without a root element, the strategy of using a single wrapping class is not applicable.

Moreover, without a root element, the styling will apply to both the current component and its children. Consider this example:

<!-- Scoped.svelte -->
<style>
   span { color: red }
</style>

<div>
  <span>I should be red</span>
</div>

<slot />
<!-- App.svelte -->
<script>
  import Scoped from './Scoped.svelte'
</script>

<Scoped>
  <span>I should not be red</span>
</Scoped>

The <span> in App.svelte is considered a child of the Scoped component within the DOM structure.

Note: If you aim to scope styles only to the current component and its children, use the :global pseudo selector:

<style>
  /* It is necessary to have a wrapping element for this approach */
  div :global(span) { color: blue }
</style>

The style defined with the div selector will exclusively affect the children of the component (within the DOM hierarchy), not elements outside of it.

Answer №2

It is true that the level of specificity remains the same, but there is a crucial difference in the way Svelte handles components compared to traditional HTML elements.

.my-component-01 h1 { ... }

In Svelte, there is no default parent HTML element wrapping components. This means that components do not have a predefined parent element like they would in standard HTML.

For example, if you look at this REPL, you'll see that even though one of the h1 tags comes from an imported component, both h1 tags end up next to each other in the compiled markup:

<body>
  <h1 class="svelte-1k0q8ta">This is green</h1>
  <h1 class="svelte-1wsvnfu">This is red</h1>
</body>

If Svelte were to follow the natural order and wrap components with parent elements, the markup would look something like this:

<body>
  <someelement class="my-component-01">
    <h1>This is green</h1>
  </someelement>
  <someelement class="my-component-02">
    <h1>This is red</h1>
  </someelement>
</body>

This approach could lead to unexpected behavior when using CSS properties like flexbox or grid that rely on specific parent-child relationships. While having repeated classnames for elements may not be ideal for frequent browser inspectors, it is necessary to ensure that CSS functions as intended for the majority of users.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to add flair to the HTML <title> tag?

Just a quick question - I'm wondering if there is a method to apply CSS styles to an HTML element. Here's an example declaration: title { color: red; font-family: 'Roboto', sans-serif; } ...

Utilizing multiple dropdown buttons in navigation menu items with Bootstrap 4

Trying to find a solution for having sub menus within the menu items. There are 2 dropdown buttons (Reports and Views) within a menu item that is itself a dropdown item. Clicking on the first button displays the submenu below, but clicking on the second ...

Replicate the ctrl+/- function through coding

While browsing with your browser, you have the ability to adjust the font size by using CTRL + + or CTRL + -. Is there a way to replicate this functionality through code, such as with JavaScript? I am looking to add buttons on my website that allow users ...

The ease of use and availability of radio buttons

When clicking on the first or second value of the radio button, it selects the first option. Here is the HTML code: @supports(-webkit-appearance: none) or (-moz-appearance: none) { input[type='radio'], input[type='checkbox'] { ...

Issues with 'floating' unordered lists

.menu li { float: left; color: #fff; font-weight: bold; } .menu li a { display: block; height: 20px; min-width: 110px; text-decoration: none; border-radius: 3px; padding: 4px; padding-left: 6px; padding-right: 6p ...

Why does the last-of-type selector work, but the first-of-type doesn't seem to?

The SCSS code snippet below is causing me some confusion: li { &.menu-item-type-custom { margin-bottom: 10px; a { // } &:last-of-type { margin-bottom: 40px; } &:first-of-type { margin-top: 40px; ...

The functionality of jQuery .Show() may be affected when a negative margin is present in the

Check out this demo on Codepen that showcases the issue: http://codepen.io/theclarkofben/pen/xKhsd The .Show() effect isn't working as expected due to the negative margin applied to the div. Can someone shed light on why this behavior is occurring? ...

Margins and borders with a negative impact

I have a collection of images that I am trying to stack using negative margins. However, because stacking them without defined boundaries can lead to visual confusion, I thought about adding borders around each image. Surprisingly, while the images are sta ...

Require assistance in getting a slider operational

Hello there! I could really use your assistance with this code. I have been trying to make it work using JavaScript, but I'm determined not to incorporate any external JS files. Here is the snippet of JavaScript code I am working with: "use strict"; ...

Two-column dropdowns without the use of tables

I am looking to create a drop-down menu with the following structure: | Heading ---------------- action | Item action | Item action | Item action | Item The action could represent "Change" and Item could be something like "Users". To maintain ...

explore the route with the help of jquery scrolling feature

Is there a way to implement scrolling functionality for tab headers similar to this demo? I have a list of elements within a div that I need to scroll like the tabs in the demo. I attempted to achieve this by setting the position of the inner elements to ...

Arrange divs in a grid layout with evenly distributed dynamic spacing

I am not a big fan of bootstrap, so I was wondering if it is possible to achieve the layout without using it. I have 6 divs that I want to arrange in 2 rows and 3 columns. I need the space between each row/column to be precise. While I can calculate this ...

Transforming CSS styles into Material UI's makeStyles

My CSS styling was originally like this const Root = styled.div` display: flex; flex-direction: row; margin: 0 auto; width: 100%; position: relative; @media (min-width: ${(p) => p.theme.screen.md}) { width: ${(p) => p.theme.screen.md ...

Setting the font-size in HTML/CSS to dynamically adjust and fill the entire width and height of its

I'm trying to make a <div> element adjust its size based on the browser window. Within this <div>, there is a paragraph of text: <div style="width:80%; height:80%; margin:10%;"> <p>Paragraph of text. Paragraph of text. Pa ...

Enhancing the bottom border of an unordered list when incorporating styled bullets

I have a list with some items. I used a CSS trick to style the bullet as a circle. However, I would like to add a border underneath each item to separate them. Because I removed the default bullets using list-style: none, the "bullet" is positioned -1em, ...

I am having trouble debugging the Twitter Bootstrap v4-alpha grid. The col-sm-offset-* class doesn't seem to be

Something has been altered somewhere, causing col-sm-offset-*s to stop functioning entirely. For instance, when attempting to split the screen in half and only display content on the right side, I typically would use: <div class="container"> < ...

It appears that the React MUI Grid is causing the page or its container to experience overflow issues

I'm utilizing Grid to maintain the organization of the entire page, but I keep encountering an overflow issue when adding multiple Grid items. This results in the scrollbar appearing even though the container size remains the same. Dashboard.tsx is pa ...

Splitting a list of accordions into two columns with CSS and React - a step-by-step guide!

I am looking for a way to showcase a list of Accordions in a two-column layout. Each Accordion consists of both a Summary and Details section, with the Details being visible only when the Summary is clicked. Unfortunately, I won't delve into the imple ...

Method for eliminating double quotes from a string bound in Angular

Check out this code snippet: var app = angular.module('umovie-app'); app.directive('renamable', function($sce) { return { scope: { model: '=model', }, link: function(scope, elements, attributes) { ...

Tips for incorporating unique images into each individual flex box

I am new to the world of coding, having just embarked on this journey less than a week ago. Following a tutorial by a developer on YouTube, I tried to add my own twist to the project in order to differentiate it from the original. However, I've hit a ...