Angular2 css :host applying but not visible in browser - css

I am having a bizarre issue whilst creating my first Angular2 app.
I am applying some CSS to a component host (example-component) yet it doesn't appear in the browser?
This is my first time posting for Angular in SO, so hopefully I include everything needed to attain some help.
example.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'crate',
templateUrl: './app/folderA/folderAB/crate.html',
styleUrls: ['./app/folderA/folderAB/crate.css']
})
export class MyComponent {}
index.html
crate.html
<div class="background">
<div class="content">
<p>Content</p>
</div>
</div>
crate.css
:host-context(.lg){
width: 100%;
background-color: #000;
border-radius: 25px;
}
What I don't understand, is that I open this in chrome & firefox, and I see the following CSS stated under rules for example.component.
.lg[_nghost-ims-2], .lg [_nghost-ims-2] {
width: 100%;
background-color: #000;
border-radius: 25px;
}
It is correctly applying the CSS to example-component, but it is not being displayed / rendered in browser. What am I doing wrong / missing?
EDIT
The exact same issue applies even if I change crate.css to:
crate{
width: 100%;
background-color: #000;
border-radius: 25px;
}

Any component with an unrecognized tagName like <crate></crate> is created as a HTMLUnknownElement and has empty values for all the style properties, if you want it to behave like a div then add display: block; to your stylesheet.
See Browsers' default CSS for HTML elements for additional resources on the default css for different browsers.

Related

Applying CSS to scoped component of Quasar element

I am working on a quasar/vue app. I want to style the dialog popup within one component. I'm using scoped CSS, and if the CSS is not scoped, the style works. If the CSS is scoped, the CSS does not work. I only want to style this dialog in this one component.
The template code calling the dialog:
<div class="-nav">
<q-select
outlined
dense
v-model="select"
:options="options()"
behavior="dialog"
style="width: 100px"
/>
The CSS element is:
<style scoped>
.q-dialog__inner {
width: 400px;
background-color: red;
}
</style>
This does not work:
:deep(.q-dialog__inner) {
width: 400px !important;
background-color: red;
}
I noticed that the global quasar style is marked with !important
codepen: https://codepen.io/kiggs1881/pen/oNoOzEj
.q-dialog__inner > div {
width: 400px !important;
background-color: red !important;
}
hope it helps
Have you tried to put the parents class in front of the selector like this?:
(If have seen this here) and it worked for me inside an expansion item.
.q-dialog :deep(.q-dialog__inner) {
width: 400px !important;
background-color: red;
}
I think everything is provided in the quasar.dev documentation if that doesnt help try using on hover => funtion-To-Display-Popover-In-Specific-Component
there are many ways to counter this problem using scoped is not the only one

How to override materialize css in React

I am using react to build simple app, and using Materilize css. In my UserProfile Component class importing UserProfile.css import "./UserProfile.css.
/* UserProfile.css */
.custom-class {
margin-top: 30 !important;
color: pink;
}
UserProfile in render method have
<h1 className="custom-class">Title</h1> // Margin is not applyed, but color is pink
I have an option to
<h1 style={{ marginTop: 30, color: "pink" }}>Title</h1>
this works fine, but I prefer style code in css files.
I am not sure maybe that issue has no relation to overriding.
you should use px in css files, change your code to margin-top: 30px !important; and it should work.
And if you want to check overriding issues in css, you can inspect your code(with right click your browser and choose inspect) and check if its crossed or not.
You'll need to use camelCase for your classname, so .customClass instead of .custom-class.
Then your import statement should look like:
import css from './UserProfile.css`;
and in your component:
<h1 className={css.customClass}>Title</h1>
Read up on CSS Modules for more information.
You don't have a unit for margin-top in your css class
.custom-class {
margin-top: 30px !important;
color: pink;
}

Only a few CSS files apply their styles in React

I am creating a ReactJs app, and am trying to apply styles. I load styles in the normal way (without webpack css modules):
import React, {Component} from 'react';
//styles
import './Header.css';
class Header extends Component {
render() {
return(
<div className='header'>
<h1>Save</h1>
</div>
);
}
}
The styles that I have for the header class apply, and everything is groovy. But for about 50% of my ReactJs files and their subsequent CSS files, the class styles do not apply. There is no error either, it finds the CSS and just doesn't apply the styles on some of the files.
I have no idea what is wrong, thanks!
EDIT 1
The header.css file:
.header {
width: 100%;
top: 0;
left:0;
text-align: right;
height: 100px;
margin: 0 auto;
}
.header h1 {
margin: 0;
margin-right: 40px;
cursor: pointer;
}
Edit 2
Example of class whose styles don't apply
Matrix.js:
import './Matrix.css';
render() {
const {users, selectedDivision} = this.state;
return(
<div className='container' style={{display:'grid', gridTemplateColumns:'200px 1fr'}}>
<div style={{textAlign: 'left'}}>
<input type='text' placeholder="Search Divisions" onChange={(e)=>this.search(e)} className='searchDivs'/>
<Scroller divisions={this.state.displayDivisions} handleSelectedDivisionChange={this.handleSelectedDivisionChange.bind(this)} />
</div>
<div style={{marginLeft: '10px'}}>
<Division division={selectedDivision} users={users} addToParentDivisions={this.handleNewUserAddedToDivision.bind(this)}/>
</div>
</div>
);
}
Here my work around has been to use inline styles but I want to try to avoid this as a best practice
Edit 3
Looking at dev tools in Chrome it shows that my css is not loaded because they are invalid property values?
So React is loading in the styles, but just refusing to display because they are invalid?
Just had the exact same problem!
Solution: Remove quotation marks (") around your property values.
Inline styles in JS require them but CSS does not.
I work in CSS every day I should've known this.
VSCode didn't pick it up either.
(Facepalm)
Assuming everything else is working properly like importing the right css file, using className, etc. I've found that, on rare occasions, something gets stuck in the browser cache and needs a full refresh.
Mac: Command+shift+R
Win: Ctrl+shift+R

md-menu override default max-width in Angular 2

I'm using Angular 2 , Angular Material and I am willing to display more data in a md-menu and, therefore, I need to set the max-width of the md-menu to a higher value. Its default value is of 280px.
<img src="/assets/images/ic-notifications.png" [mdMenuTriggerFor]="appMenu"/>
<md-menu #appMenu="mdMenu" [overlapTrigger]="false" yPosition="below" xPosition="before" class="notifications-dropdown">
<button md-menu-item >
<div class="row notification-row">
<div>
<span class="image-container"> Option 1 </span>
</div>
</div>
</button>
</md-menu>
In CSS file, I do this:
.mat-menu-panel.notifications-dropdown {
max-width:none;
width: 100vw;
margin-left: -8px;
margin-top: 24px;
overflow: visible;
}
.notification-row{
width: 424px;
}
In console, I can identify the class where the default value is set: max-width:280px; , and when I edit it in my console, it works perfectly, but even though I try to override it in my CSS code, I am not able to do that. I tried this, also:
.mat-menu-panel{
max-width: 600px;
}
And this:
.cdk-overlay-container .mat-menu-panel{
max-width:600px;
width: 100vw;
margin-left: -8px;
margin-top: 24px;
}
How can I override this default value?
Set the View Encapsulation to None on your component:
#Component({
templateUrl: './my.component.html' ,
styleUrls: ['./my.component.css'],
encapsulation: ViewEncapsulation.None,
})
Then in your component css you can do exactly what you tried:
.mat-menu-panel.notifications-dropdown {
max-width:none;
width: 100vw;
margin-left: -8px;
margin-top: 24px;
overflow: visible;
}
.notification-row{
width: 424px;
}
View Encapsulation = None means that Angular does no view
encapsulation. Angular adds the CSS to the global styles. The scoping
rules, isolations, and protections discussed earlier don't apply. This
is essentially the same as pasting the component's styles into the
HTML.
In some cases the wrapper over .mat-menu-panel can be .cdk-overlay-pane, in that case css should be something like this.
.cdk-overlay-pane.mat-menu-panel {
max-width: your_custom_value
}
Due to the css specificity rules, 2 classes of specificity are required in order to override the defaults.
The same crazy problem for me... how I solved:
::ng-deep .cdk-overlay-pane .mat-menu-panel {
max-width: 436px;
}
At component SASS file
See: Angular Component Styles - View Encapsulation
and issue comment by #gaiki https://github.com/angular/material2/issues/4462

Angular2 - adding [_ngcontent-mav-x] to styles

I'm setting up a basic angular app, and I'm trying to inject some css to my views. This is an example of one of my components:
import { Component } from 'angular2/core';
import { ROUTER_PROVIDERS, ROUTER_DIRECTIVES, RouteConfig } from 'angular2/router';
import { LandingComponent } from './landing.component';
import { PortfolioComponent } from './portfolio.component';
#Component({
selector: 'portfolio-app',
templateUrl: '/app/views/template.html',
styleUrls: ['../app/styles/template.css'],
directives: [ROUTER_DIRECTIVES],
providers: [ROUTER_PROVIDERS]
})
#RouteConfig([
{ path: '/landing', name: 'Landing', component: LandingComponent, useAsDefault: true },
{ path: '/portfolio', name: 'Portfolio', component: PortfolioComponent }
])
export class AppComponent { }
Now the .css file is requested from my server, and when I inspect the page source, I can see it was added to the head. But something weird is happening:
<style>#media (min-width: 768px) {
.outer[_ngcontent-mav-3] {
display: table;
position: absolute;
height: 100%;
width: 100%;
}
.mainContainer[_ngcontent-mav-3] {
display: table-cell;
vertical-align: middle;
}
.appContainer[_ngcontent-mav-3] {
width: 95%;
border-radius: 50%;
}
.heightElement[_ngcontent-mav-3] {
height: 0;
padding-bottom: 100%;
}
}</style>
gets generated from this file:
/* Small devices (tablets, 768px and up) */
#media (min-width: 768px) {
/* center the mainContainer */
.outer {
display: table;
position: absolute;
height: 100%;
width: 100%;
}
.mainContainer {
display: table-cell;
vertical-align: middle;
}
.appContainer {
width: 95%;
border-radius: 50%;
}
.heightElement {
height: 0;
padding-bottom: 100%;
}
}
Can somebody please explain where the _ngcontent-mav tag comes from, what does it stand for and how to get rid of it?
I think this is the reason why my style is not getting applied to my templates.
If you need more info about the app structure, please checkout my gitRepo, or ask and I'll add the code to the question.
Thanks for the help.
update2
::slotted is now supported by all new browsers and can be used with `ViewEncapsulation.ShadowDom
https://developer.mozilla.org/en-US/docs/Web/CSS/::slotted
update
/deep/ and >>> are deprecated.
::ng-deep replaces them. ::-deep is also marked deprecated in source and the docs, but this means that it will also be removed eventually.
I think it depends on what W3C comes up with for theming the shadow DOM (like https://tabatkins.github.io/specs/css-shadow-parts/)
It's basically a workaround until all browsers support that natively and ViewEncapsulation.Emulated can be removed entirely.
::ng-deep is also supported in SASS (or will be, depending on the SASS implementation)
original
View encapsulation helps to prevent styles bleeding into or out of components. The default encapsulation is ViewEncapsulation.Emulated where classes like _ngcontent-mav-x are added to component tags and also styles are rewritten to only apply to matching classes.
This emulates to some degree the default behavior of the shadow DOM.
You can disable this encapsulation adding encapsulation: ViewEncapsulation.None to the #Component() decorator.
Another way is the recently (re-)introduced shadow piercing CSS combinators >>>, /deep/, and ::shadow. These combinators were introduced for styling shadow DOM but are deprecated there. Angular introduce them recently until other mechanisms like CSS variables are implemented.
See also https://github.com/angular/angular/pull/7563 (https://github.com/angular/angular/blob/master/CHANGELOG.md#200-beta10-2016-03-17)
>>> and /deep/ are equivalent and using this combinators makes the styles ignore the the added helper classes (_ngcontent-mav-x)
* >>> my-component, /* same as */
* /deep/ my-component {
background-color: blue;
}
applies to all my-component tags not matter how deep they are nested in other components.
some-component::shadow * {
background-color: green;
}
applies to all elements in the template of some-component, but not further descendants.
They can also be combined
* /deep/ my-component::shadow div {
background-color: blue;
}
this applies to all div elements in the template of all my-component templates no matter how deep my-component is nested in other components.
/deep/, >>>, and ::shadow can only be used with
encapsulation: ViewEncapsulation.None
encapsulation: ViewEncapsulation.Emulated
encapsulation: ViewEncapsulation.Native when the browser supports them natively (Chrome does but prints a warning in the console that they are deprecated) or
when the browser doesn't native support shadow DOM and the
web_components polyfills are loaded.
For a simple example see also the Plunker from this question https://stackoverflow.com/a/36226061/217408
See also this presentation from ng-conf 2016 https://www.youtube.com/watch?v=J5Bvy4KhIs0
You should try this,
import {ViewEncapsulation} from 'angular2/core';
#Component({
...
encapsulation: ViewEncapsulation.None,
...
})

Resources