Whats the difference between /deep/ ::ng-deep? - css

Could you please tell me, the differences between the below two scss styles?
I didn't get the clear idea about this.
:host {
display: inline-block;
/deep/ {
span {
color: red;
}
}
}
:host {
display: inline-block;
::ng-deep {
span {
color: red;
}
}
}

The main difference is, that ::ng-deep is supported by SASS, while support for /deep/ was removed. This is the reason why ::ng-deep was added to Angular in addition to /deep/
Besides that, both are deprecated in Angular, because when native shadow DOM support in all browsers becomes usable, they will probably remove ViewEncapsulation.Emulated

Related

How to style :host based on direct parent?

I've got a custom component <ui-title> that I wish to style differently based on what its direct parent element is.
For example, if it appears within <ui-section>, style it YELLOW. Within <ui-card> style it BLUE. If it appears anywhere else, style it GREEN.
Here's what I've tried:
:host {
background-color: green;
}
:host-context(ui-card) {
background-color: blue;
}
:host-context(ui-section) {
background-color: yellow;
}
This doesn't work because if an element is nested within both <ui-section> and <ui-card> because both sets of styles would be applied. I wish to apply a set of styles based strictly on the direct parent of the :host element.
Here's a StackBlitz that shows my issue.
I found that you can combine :host and ::ng-deep from this answer after few hours of searching and trying different combination of ::ng-deep, :host and :host-context.
https://stackblitz.com/edit/angular-ivy-yf1uff?file=src/app/ui-title/ui-title.component.css
So just moved the style related to the ui-card and ui-section to their own stylesheet and combine :host and ::ng-deep with child selector >
ui-card.component.css
:host > ::ng-deep ui-title {
font-size: 10px;
background-color: blue;
}
ui-section.component.css
:host > ::ng-deep ui-title {
background-color: yellow;
}
ui-title.component.css
:host {
display: block;
padding: 5px;
border-radius: 10px;
background-color: green;
}

CSS property 'cursor' not working with :host selector

I'm trying to figure out how to apply the property cursor when using :host selector.
Others properties are correctly applied, but not cursor.
:host([disabled]) {
color: #626878;
background-color: #C0C4CB;
cursor: not-allowed!important;
}
:host refer to a web component made with LitElement.
Thanks for your help
Runs fine:
customElements.define("my-element", class extends HTMLElement {
connectedCallback() { // so attributes can be queried
this
.attachShadow({mode:"open"})
.innerHTML = `<style>
:host {
display: inline-block;
}
:host([disabled]) {
cursor: not-allowed !important;
background: pink !important;
color: grey !important;
}
</style>
<h1><my-element
${this.hasAttribute("disabled")?"disabled":""}></h1>`;
}
})
<style>
my-element{
cursor: pointer;
background: lightgreen;
color: green;
}
</style>
<my-element></my-element>
<my-element disabled></my-element>
Requires !important
From https://web.dev/shadowdom-v1/
One gotcha with :host is that rules in the parent page have higher
specificity than :host rules defined in the element. That is, outside
styles win. This allows users to override your top-level styling from
the outside. Also, :host only works in the context of a shadow root,
so you can't use it outside of shadow DOM.

With scss #extend pseudo selected CSS

One can do #extend .foo but apparently not #extend .foo:focus.
I'm dealing with a 3rd party component which adds it's own focused class when it considers it is focused. Using #extend to apply Bootstrap styles works fine, but because the 3rd party component does not get a :focus the .form-control:focus is never matched.
My SCSS in principal would be:
.thirdparty {
#extend .form-control;
}
.thirdparty.thirdparty-focused {
#extend .form-control:focus;
}
#extend .form-control:focus; does not compile however.
Currently I can't figure out how to do this without copying the .form-control:focus CSS into .thirdparty.thirdparty-focused, which is obviously rather unideal.
Is some sort of #extend .form-control:focus; equivalent possible, and if not, any suggestions better than copying N lines of CSS to match the rest of Bootstrap?
#extend .form-control:focus will act as a selector, specifically looking for a rule named .form-control:focus. Here is an illustration.
The best solution to your problem would be to outsource the :focus pseudo-selector of the original Bootstrap class, using the %-selector, and then re-extend it into it - so that you could call it seperately.
%focus {
color: #2196f3;
}
.base {
color: #000;
&:focus {
#extend %focus;
}
}
div {
#extend .base;
&.focus {
#extend %focus;
}
}
// Other Bootstrap components can still call `#extend .base;`
This will compile to:
.base:focus, div:focus, div.focus {
color: #2196f3;
}
.base, div {
color: #000;
}
When I tried this, the error message basically told me what to do:
SassError: compound selectors may no longer be extended.
Consider `#extend .form-control, :focus` instead.
Using this should work (don't forget necessary imports to bootstrap):
.thirdparty.thirdparty-focused {
#extend .form-control, :focus;
}

Why setting a CSS role with :host ::ng-deep into an angular component CSS is not working?

I am not so into Angular and CSS and I have the following poblem trying to define a CSS related to a specific component (into the .css file of a component).
If I do in this way:
.p-column-title {
display: none;
}
it works fine. But if I do in this way (I obtained it from the PrimNG showcase example):
:host ::ng-deep {
.p-column-title {
display: none;
}
}
The CSS style is not applied.
Why? What is wrong? From what I have understand the :host ::ng-deep is used to let be global style the CSS role...so maybe it is not the correct way declare in this way into the CSS of a specific component.
I think that I am missing some piece...
I think you have to make it like this:
:host ::ng-deep .p-column-title{
display: none;
}

Why CSS attribute selector followed by element tag is slower?

According to Vue docs here:
Due to the way browsers render various CSS selectors, p { color: red }
will be many times slower when scoped (i.e. when combined with an
attribute selector). If you use classes or ids instead, such as in
.example { color: red }, then you virtually eliminate that performance
hit
So if you put the following in the Vue's style section:
<style scoped>
.parent .child {
background-color: red;
}
.parent p {
background-color: red;
}
</style>
The VueJs will transform it into this:
<style>
.parent[data-v-12345] .child {
background-color: red;
}
.parent[data-v-12345] p {
background-color: red;
}
</style>
The document says, the second selector is many times slower than the first one.
Can someone explain why the second selector is slower?

Resources