Vue 3 style scoped would effect for components - vuejs3

<script setup lang="ts">
</script>
<template>
<div>
<el-button>a</el-button>
<el-button>b</el-button>
</div>
</template>
<style scoped>
.el-button{
margin-right:10px;
}
</style>
I use vue2 before and I think .el-button would not effect for the el-button because of the scoped. But it effects with Vue 3.
I want to know why.

Scoped style only affects the component in which it is defined. Hence, your current file. So, it is quite normal this 2 buttons to be affected by your "margin-right" property. But if you put another buttons to your another files/components, you will see they will not be affected by this "margin-right" setting. That's why, it is important to put "scoped" indicator not to mess things up.
But I have to note that, the experience I gained during my usage of Element-Plus showed me that your custom style settings crushed by Element-Plus component's built-in style bindings. To overcome this:
Option 1 is to put your style settings to a separate css file which will be loaded after the Element-Plus so that your styles are not be overwritten.
Option 2 is to use styles in a way:
<template>
<div>
<el-button style="margin-right: 10px;"></el-button>
</div>
</template>
instead of:
<template>
<div>
<el-button class="button-style"></el-button>
</div>
</template>
<style scoped>
.button-style{
margin-right:10px;
}
</style>
In my opinion, your experience may caused by Element-Plus style overwrite matter instead of Vue version.

Related

react bootstrap tabs custom class not working

I use react bootstrap tabs component but when i use a custom css within this nav-link with a custom parent class indicator its not working.
<Tabs
defaultActiveKey="signup_renter"
id="uncontrolled-tab-example"
className="mb-3 approval-details-tab"
>
<Tab eventKey="signup_renter" title="About Car">
<div className="signup-renter">
this is signup renter tab
</div>
</Tab>
<Tab eventKey="signup_host" title="Details">
<div className="signup-host">
this is signup host tab
</div>
</Tab>
</Tabs>
Here is my css parent indicator:
.approval-details-tab > .nav-tabs .nav-link.active::before {
content: "";
background: #524eb7;
width: 30px;
height: 3px;
position: absolute;
top: 63% !important;
}
I use .approval-details-tab class as a parent class of nav-tabs but without parent class it works. but i need a parent class for separate design.
From the React-bootstrap documentation:
Because React-Bootstrap doesn't depend on a very precise version of Bootstrap, we don't ship with any included CSS. However, some stylesheet is required to use these components.
How and which Bootstrap styles you include is up to you, but the simplest way is to include the latest styles from the CDN.
CDN link: https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css
Add CDN at index.html file inside tag like this:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css"/>
Now, to override any class of `react-bootstrap', you have to use "!important" on your custom css. If you want to override the background color, use "!important" beside that css property.
Example:
.approval-details-tab{
background: #524eb7 !important;
}
To get more clear understanding of your problem, please mention which css-property you want to override of a bootstrap class. Thanks!
In React, the parent-children relationship is a bit complicated. Although a component in React seemed to be the direct child of another component, when translated to normal HTML, it doesn't. For example, take a look at this code
<div className="parent">
<Tabs className="children">
some other components inside
</Tabs>
</div>
Does div the direct parent of the component Tabs? It is not. The above code, when being translated to normal HTML component would look roughly like this
<div className="parent">
<div>
<div className="children">
some other components inside
</div>
</div>
</div>
As you can see, the element that bears the className children is no longer the direct child of the parent component. That is why in React, it is not a good idea to style components using parent-direct children relationship.
If you just want to do this way of styling because you want to avoid naming conflict, you can try out CSS Module
If you want to read the detail on how the Tabs component behave, you can read the source code

How to apply CSS from parent component?

There is a React component using Emotion called OtherComponent:
OtherComponent:
...
return <div css={otherComponentStyles}>
<div className='something'>
</div>
</div>
And another component called MainComponent that uses OtherComponent:
MainComponent:
...
return <OtherComponent css={mainComponentStyles} ... />
What happens in this situation is that OtherComponent properly uses otherComponentStyles. But it ignores mainComponentStyles.
But what I would like to do is to apply style to OtherComponent from the level of MainComponent.
I know i can wrap OtherComponent into a div, ad set css=... to the div. But it is a nasty fix of the problem.
Hence the question: how to apply CSS with Emotion from parent component aka MainComponent?
You are not applying those styles to any html tag, it's not <OtherComponent> which is rendering, it's the <div> which is rendering to the page, so you must apply styles to a valid html tag.

Why doesn't Svelte scope the tag under a class but use individual tag.class to style a component?

When a component has some CSS styles, it is natural to use
.my-component-01 h1 { ... }
.my-component-01 h2 { ... }
to scope the styles, but Svelte uses
h1.svelte-hlsza1{color:orange}
h2.svelte-hlsza1{background:yellow}
Is it more robust to actually scope it under a certain class (the top method) instead, because at least inside the HTML markup, the compiled code can just be:
<div class="svelte-hlsza1">
<h1> ...
<h2> ...
instead of repeating the class name every time. (and I think the specificity is the same: 1 class and 1 tag name).
Because Svelte doesn't require a single top level element.
<!-- no problem for Svelte -->
<h1>...</h1>
<h2>...</h2>
In fact it doesn't even require elements at all.
<script>...</script>
<!-- this is the end of the component (still no problem for Svelte) -->
Whatever... Without a root element, the single wrapping class strategy is not applicable.
Also, doing so would not scope only to the current component, but to 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 not part of the Scoped component, but it is a child of it, in the DOM.
Note: if scoping to the current component and its children is what you want, the trick is to use the :global pseudo selector:
<style>
/* note that you do need a wrapping element, this time, to do that */
div :global(span) { color: blue }
</style>
The div selector style gets scoped, so we're only targeting children of this component (DOM wise), not above.
You're correct that the level of specificity is the same but this rule:
.my-component-01 h1 { ... }
is assuming that there is an element that wraps the h1, in Svelte this is never the case. There is no default parent HTML element to components and there should not be.
If you inspect this REPL for example; despite one of the h1 tags originating from an imported component both h1 tags are right next to one another in the compiled markup like so:
<body>
<h1 class="svelte-1k0q8ta">This is green</h1>
<h1 class="svelte-1wsvnfu">This is red</h1>
</body>
If the natural way were to be the case then Svelte would have to modify the compiled markup to be 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 would cause unpredictable results when using css-flex or grid which depend on parent-child relationships. So although the repeated classnames for elements may be annoying for someone who inspects the browser often (most users don't) it's a necessary evil that allows CSS to work as expected.

How to reflect BEM blocks in Aurelia views

I'm about to start a new project using Aurelia and I'm considering to use it in conjunction with CSS BEM methodology.
First question: Is this basically considered a good match or are there any alternatives which "fit" better with Aurelia?
Main question:
Best explained with an example for some custom Aurelia view (an app header):
<template>
<div class="AppHeader">
<span class="AppHeader-logo"></span>
<span class="AppHeader-text"></span>
<app-menu></app-menu>
</div>
</template>
When embedded into another view, this leads to a resulting DOM like this (simplified):
<app-header>
<div class="AppHeader">
<span class="AppHeader-logo"></span>
<span class="AppHeader-text"></span>
<app-menu>
<!-- ... -->
</app-menu>
</div>
</app-header>
Obviously, the wrapper div with the AppHeader class is kind of superfluous since there's also the app-header tag. Unfortunately it doesn't seem to be possible to assign the CSS class AppHeader (which is needed for BEM) to the base element of the view (the template tag in the view file).
Are there any alternative ways that I'm not aware of or is it considered "good" practice (or at least acceptable) to have many wrapper elements inside views which somehow bloat the DOM?
I just realized, that putting custom classes on the custom elements themselves (the template) actually works, so I can simply write something like this:
<template class="AppHeader">
<span class="AppHeader-logo"></span>
<span class="AppHeader-text"></span>
<app-menu></app-menu>
</template>
Edit / Additional info
This won't work if the view is a "base view" of a route since the template element won't be rendered at all in this scenario but is replaced by the router-view element.
I believe that even a hundred extra DOM nodes is not a problem for contemporary browsers but if it's really important to avoid them you may try custom tags instead of classes (see list of restrictions here https://en.bem.info/methodology/faq/#why-are-custom-tags-not-used-for-blocks-in-bem).
Perhaps the #containerless will solve your problems:
In your view model:
#containerless
export class AppHeader {
...
}
In this way, the <app-header> container will not be rendered.
If your component is a view-only component, you can declare containerless in the <template> tag:
<template containerless>
<div class="AppHeader">
<span class="AppHeader-logo"></span>
<span class="AppHeader-text"></span>
<app-menu></app-menu>
</div>
</template>

Apply styles to only to one element

I am including styles in normal way like this:
<link rel="stylesheet" href="/css/boostrap.css" type="text/css" />
this styles has a lot of styles which destroy my main view, it applies to body element, is it possible to applay the style only to one particular div?
Put that <div> into a separate page and include bootstrap CSS only in that page.
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="/css/boostrap.css" type="text/css" />
</head>
<body>
<div>This is your DIV</div>
</body>
</html>
Your main page won't be touched by that and you'll be able to display that div inside your main page simply using an iframe, change (for example) this:
<div>This is your DIV</div>
To this:
<iframe src="url of the other page"></iframe>
Of course you may need to change little bit the logic of your page to accommodate this (primary I guess because of server side C# code, for client side JavaScript code it should be easier because the come from the same domain).
Yes, you can do that by ID:
<div id="myDiv"></div>
and then the CSS would be:
#myDiv { ... }
and that will apply that style to anything named myDiv. You could also use classes:
<div class="someClass"></div>
and then the CSS would be:
.someClass { ... }
and that will apply that style to anything with that class attached.
Based on what you're describing, surrounding the generality of the CSS that's breaking the already defined CSS, you're going to want to get rid of those general element styles and use ID's because it sounds like you're trying to merge some CSS.
You try to remove all styles of body with javascript code, and after that, after you add a name/id to the body style in your correct css, set this as class attribute of your body. (js code too after the document is completely loaded)
Another (stupid) solution depends on what do you have in the css file. Do you can edit the /css/boostrap.css, simply replace all body word with ".body1" (fe => make a class from it)?

Resources