Altering the CSS added by an Angular Directive? - javascript

How do we override the CSS created by an angular directive. For example when we add the add the sort directive to the material data table it creates this problem (It overrides the layout of the column header)..
Overriding the CSS via styles.scss or the components local CSS, does not work, because the directive adds an inline style which has priority. Also tried adding !important to the CSS definition override, but no love.
Thoughts?

I can suggest one method, write a custom CSS class in your component's CSS/SCSS file and apply it using a condition with NgClass directive,
execute your condition within onInit.
just try and see, I hope it'll work

You can either use NgStyle or Angular Style Binding if classes' style is not being applied. Best way is to use ngdeep
If this still doesn't work put it on a setTimeout or ngAfterViewChecked (Not recommended tho.).

Related

Setting :root custom properties inside Shadow DOM

my use case is basically the following: I'm building a component library which should render a component in a web component using shadowRoot.
I have two CSS files:
component-library.css styles the component library and should not leak into the web components (I'm aware that they do when the components use inherit. This is fine.).
project.css is the global CSS file for the project, defining lots of custom properties inside :root {}. I am NOT able to change that.
What I now want is to use project.css inside the shadowRoot to style the components. The reason that it should be inside the shadowRoot is that I don't want this file to affect the component library.
Right now, when I'm trying to implement it, everything works as I want it to except that the custom properties from project.css is missing.
My understanding is that this can't work as the project.css would have to use :host {} instead of :root {}.
Is that correct? Would there be any way to achieve this though?
Thanks a lot!

Apply css style to all primeng dialogs in my angular app

I am using prime ng dialog all over my angular application. I can change each specific dialog style by using ng-deep. For eg I have contact us page for which I have these files:
contact.html
contact.component.ts
contact.css
So I place the below css in contact.css and it changes the contact us dialog title bar color.
:host ::ng-deep .ui-dialog .ui-dialog-titlebar{
background-color: red
}
I want to do this for all the dialogs in my application, how can I do this? I placed the same css in style.css file in src folder and it didn't work.
So angular components by default employ a very handy strategy of Style Encapsulation which makes it so that styles don't bleed out into other components and cause unwanted effects.
You can utilize ng-deep like you have to allow styles defined within it to be inherited by child components of where it's specified.
However for things to be globally inherited you'll want to define them highest up in the order of inception so those styles cascade down to selectors below. In a default angular application that's not using SCSS or another pre-processor one of the easiest ways to do this is to add them to one of the first files initialized that hosts the child components such as index.html or app.component to allow components initialized afterwards to inherit them when they're rendered.
Hope this helps, cheers!

Shadow DOM/Web component styling in Ionic 4

I'm trying to understand how and where ionic 4 is injecting the styling for the web components into the dom. I'm not interested in changing it via the CSS variables but I want to be able to inspect the component and see where the styling is coming from. For example on https://ionicframework.com/docs/demos/api/alert/index.html?ionic:mode=ios
If you inspect the button:
I can see the stlying being applied but I can't see where all the styling is coming from, it's not in the css bundle, style tags on the page or directly on the element or applied to the shadow-root. Normally the host styling is part of the component e.g.
So where is the :host styling being defined and how/where is it being injected into the DOM?
So as far as I know all the styles you apply to your component are usually set innerHTML. You already found the style tag which is the first tag after the component. This is super full with stylings as always thats why you usually see just a snippet. That depends on the browser but to see all the stylings you may have to do a double click into the stylings between the style tags.
Usually when I want to read something like this I copy it into my editor and take a look there:
As you can see all your stylings are defined there. Stenciljs also load some general stylings to make sure everything looks proper. These are instantiated into your head section:
So I think Ionic 4 is using: https://developers.google.com/web/updates/2019/02/constructable-stylesheets
Which is why the styling isn't visible directly in the DOM. Credit to Fraser for working this out.

How do detect what overrides css properties of ReactJS components?

:)
I have been developing a webpage for some time now, and I decided to use a react-calendar component from here. In the beginning, when page was lightweight it worked out of the box and, following the example on the webpage, my page rendered this:
Later on in the development, as i added more complexity to the page, calendar became completely disfigured and only displays plainly, like this:
I thought something was overriding my calendar's css properties and tried putting it outside the app div like this:
<div>
<Calendar/>
<App/>
</div>
But calendar's appearance remains unchanged. After inspecting elements in browser I noticed some suspicious crossed out values:
Is there a way of preventing parent override of calendar's css properties? Or am i missing something crucial in code which would make the calendar look neat again? It always looks neat if I install and use it in a clean project (but i'd love to have a working one everywhere :D).
Thanks in advance for your advices! :)
Have a nice day!
If you have a CSS property you can almost always override it. There is no way to tell (for example using javascript) if a css value has been overridden, since it's the browser who does this. Maybe there is something in your code that changed the behaviour by adding a parent class that overrides all its children, or a major CSS style sheet like bootstrap that overrides some others. If this is your case, it's hard to tell without looking at the code.
Good news
You can completely prevent CSS inheritance, by wrapping your component in an iframe.
Or
You can have properties that can almost never be overridden, depending on CSS specificity.
According to MDN web docs:
Inline styles added to an element (e.g., style="font-weight:bold")
always overwrite any styles in external stylesheets, and thus can be
thought of as having the highest specificity.
Have a read at the complete article to understand how it works. This statement though, says that you can always override properties if they are set inline. Now, the problem of using a third-party component is that you cannot set the styles for everything used by the component, and of course the point on using a third-party component is that you don't need to bother about these configurations.
Apart from using inline styles, you can also set the !important flag to your CSS styles, but we come to the problem of the third-party component again.
I suggest these approaches:
1) Create CSS rule to reset values to initial
Basically create a rule called NoInheritanceCalendar for example, that will reset any rules before the calendar's rules.
Set your code to:
<div className="NoInheritanceCalendar">
<Calendar/>
</div>
and in your CSS:
div.NoInheritanceCalendar {
all: initial;
}
2) Wrap it in an iframe
Although not the best approach, this is the only way you could prevent inheritance at all.
3) Copy component's style sheet, add prefix class to all properties so that they are more specific.
If your third-party component's CSS is:
.rule1 {
font ...
width ...
}
.rule2 {
font ...
width ...
}
.rule3 {
font ...
width ...
}
You can create a prefix class to make those more specific:
.MyClass.rule1 {
font ...
width ...
}
.MyClass.rule2 {
font ...
width ...
}
.MyClass.rule3 {
font ...
width ...
}
and add your component in react as:
<div className="MyClass">
<Calendar/>
</div>
These tools help you with this if it is a big style sheet:
autoprefixer
prefixfree
less-plugin-autoprefix

AngularJS - Custom Directive - CSS separate file?

I'm making a custom directive <top-nav>.
Should I isolate the CSS for this in its own file?
What if it requires CSS from the main application that's shared across other pages?
Take a look at LESS and SASS css compilers.
I structure my apps like this.
/app
/directives
/fooWidget
fooWidget.scss
fooWidget.js
fooWidget.html
/directives.scss
/app.scss
/app.js
If you intend to publish it somewhere then you definitely want to isolate the CSS.
If this is only for internal use, it's a matter of preference, but I think the majority of developers would prefer if it's separate.
CSS in a separate file can still inherit from CSS defined elsewhere. Eventually you'll probably end up using Gulp to minify and combine all your CSS anyway.
I don't see that as a necessity. If you are adding a template in your directive, then keeping the css to the external file won't do any harm, as the directive gets loaded when the DOM is being parsed & the style written for the element will be loaded accordingly from the external style sheet.
Hope that helps.
It is a good practice to use an isolate CSS file to the directive. You can use a structure for the directive like this:
/clockWidget
clockWidget.css
clockWidget.js
clockWidget.html
For the directive css it self you can create a css class that wraps all the html and use that class to affect only the directive html.
for instance, create the footer-widget css class and specify that class for the html elements of the directive.
In the clockWidget.css:
span .footer-widget{
background-color: red;
}
then in your html:
<div class="footer-widget">
<span>I'm The footer</span>
</div>
This way the css class will wrap all the html, only affecting the directive html. And you can use main application css without problems.

Categories