I'm new to Angular (and Angular 5.x specifically), and am hoping someone can shed some light on something for me..
I'm trying to figure out how to read (not manipulate) the CSS style properties of a certain class that's applied to a known element.
For example, I've got a text element that has the "special-fancy-text" CSS class applied to it. How can I access that element's CSS class's properties to dynamically tell what font family, font size, color, or other options are currently set within it?
Thanks!
You can use ViewChild like this:
html
<div #filterDiv class='col-md-2' style='color: blue'>Filter by:</div>
Component
#ViewChild('filterDiv') filterDivRef: ElementRef;
ngAfterViewInit(): void {
if (this.filterDivRef.nativeElement) {
console.log(this.filterDivRef.nativeElement.style.color);
}
}
The above will display 'blue' to the console. This this for more details: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style
Though I don't think that if you use a style class that this will be able to tell you the style properties from that class.
Related
When I need a component to change slightly for a new use, I've looked at transclusion and multi-slot transclusion vs adding HTML around the component but there are still situations where a component's internal styling needs to be changed.
You can pass a style in as an input, and then set it in the template with [ngStyle].
So for a simple example i'll show how to do this with a background color.
customComponent.html
<div [ngStyle]="{'background-color': data?.backgroundColor }">
<p> the background color will be set from an input </p>
</div>
customComponent.ts
#Input('data')
data: {
backgroundColor: string;
};
parent.html
<customComponent [data]="{backgroundColor: 'grey'}"></customComponent>
Components should be self contained and programmed so they don't require refactoring whenever a new use is needed.
One solution is to add a class to the parent using ng-class, and then use regular css rules to style the child: one set of rules that requires the class to be on the parent div, and another set that doesn’t require the class to be on the parent div.
Example css:
.my_class {Normal styling}
.my_parent_div_class .my_class {Special styling goes here}
I'd like to ask for a little nudge to get my brain out of the box I got it into.
Context
Angular 4 using Angular CLI and AoT.
All methods mentioned in https://angular.io/docs/ts/latest/guide/component-styles.html describe ways to set complex CSS of a component while it is being written by a developer.
After a component is created, Angular allows to adjust individual styles and even assign various CSS class names to tags in the component as you please, all that using [ngClass], <div [class.something]="condition">, various #HostBinding decorators and some other methods.
However, none of the above can change the CSS declaration the component is using. The methods above can either (a) use what is already available in the stylesheet defined by the developer or (b) set individual CSS properties to individual HTML tags in the component's template.
Question
How would I update the CSS for the whole component on runtime so that all elements in that component respond to the new CSS?
Say I introduce a new style for a div.someClass and I want all matching elements div.someClass to reflect the new style.
Plunker
A showcase of my attempts is here: https://plnkr.co/edit/N2C40cSb7hd1AyOxWWdT
The button should be red, based on the value of MyChildComponent.styles
I think I understand why it doesn't work the way I would expect: shortly said, styles are built in the component during compilation, not runtime, including those found inside <style /> tags in the template.
But knowing why it doesn't work doesn't help me to make it work.
Any help highly appreciated.
Solution 1
Inserting a new css class is not possible ( as far as i know ) but you can insert css properties to your component dynamically.
I modified your dynamicStyles() to this
get dynamicStyles(): any{
return {'background': 'red' };
}
that returns an object instead of string because you will pass this object to ngStyle of your button.
In your template, I change the button like this
<button type="button"
[ngStyle]="styles">
Button
</button>
Here's a plunkr
Solution 2
This is something that I would not recommend but in your case it might be useful. You can add this
encapsulation: ViewEncapsulation.None
and the import
import {ViewEncapsulation} from '#angular/core'
to your #Component.You can leak your component's css so that you can use it on your child component. Then in your child component, add a [ngClass] in your button so that you can just pass a variable via #Input() if it should be red.
<button type="button"
[ngClass]="{'redButton': isButtonRed}"
>Button</button>
And in your style.css
.redButton{
background:red;
}
And in your main component.
<div>
<h2>Hello name</h2>
<my-child [isButtonRed]="true"></my-child>
</div>
Here's another plunkr
Hope this helps.
We are using bootstrap, want to overwrite one of the bootstrap class properties as shown below. I am using Asp.net MVC.
CSS
Boot strap
Panel-heading
{
Color : Red
}
Application CSS
Heading
{
Color : Green
}
HTML Page
Link Bootstrap
Link Application CSS
Issue: Still div color is Red.
Can some help me how overwrite color of boorstrap class without using !.
This is happening because when your application is loading you are loading bootstrap file first and then your application css file, which is actually the correct way to load it.
But according to css rules if you apply two classes on an element having same style then the browser will pick the one which it finds first.
It does not depends on the order in which you have applied it on your element which means
<div class = "Panel-heading Heading"></div>
<div class = "Heading Panel-heading"></div>
changing this order does not matters, what matters is which css file gets loaded first in the browser.
One way to override it is using !important which is not a good practice.
Also having a class with same name in your application is not an elegant solution as a new developer working on your application can get confused as he would not be expecting the native bootstrap classes to work in a different manner.
The other way out is to increase the specificity of your custom class.
Application CSS
div.Panel-Heading.Heading { Color : Green }
This will increase the specificity of your class by giving it more precedence and will override the previous class
You can read more about specificity over here
https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity
I have some code in HTML and CSS where HTML looks like this:
<div id="avmenu">
<h2 class="hide">Menu:</h2>
<ul>
<li>Welcome!</li>
And my CSS looks like this:
#avmenu
{
Style details
}
#avmenu li a:hover
{
Style details
}
a:hover{ Hover styles }
So above piece of code shows a menu item and does some animation like color change etc when you hover your mouse over the menu. I have show bare minimum styles sufficient to explain problem at hand.
Now when I migrate this to GWT. We have used Label as menu items, and I want to achieve same effect in GWT too. Here is what I have tried
I tried to apply CSS Style named "avmenu", this applied basic styles, but of course didn't get animation
Then I tried DOM.setElementAttribute(orgLbl.getElement(), "id", "avmenu"); but that also didn't help.
What would be my best option with minimal time and effort to achieve same effect? I can of course listen to events on Label and then change the style, but doing that for all of the widgets would be an overkill!
EDIT- More info: I am building Menu using Label, and adding that to tree
userMgmtLbl = new Label("User mgmt");
userMgmtLbl.setStyleName(HOME_MENU_LBL_STYLE);
treeItem_1 = configParentTL.addItem(userMgmtLbl);
userMgmtLbl.addClickHandler(Click logic)
One of the problems that you're running into is that Tree and TreeItem in GWT are composed of arbitrary divs, rather than ul and li as in your original html. (When indoubt you can inspect the DOM of GWT's showcase to see how the underlying widgets are created).
What this means is that your selectors, such as "#avmenu li a:hover" will no longer work.
If your navigation menu is static, your best bet is probably to use GWT ui-binders, which are basically gwts templating system. If you use a HTMLPanel as your root widget, you can effectively use all your original HTML verbatim and not worry about trying to mash all the DOM elements into corresponding widgets.
A basic widget would look something like this:
NavigationWidget.java
public final class YourWidget extends Composite {
YourWidget() {
initWidget(binder.createAndBindUi(this));
}
private static final Binder binder = GWT.create(Binder.class);
interface Binder extends UiBinder<Widget, YourWidget> {}
}
NavigationWidget.ui.xml
<ui:UiBinder
xmlns:gwt="urn:import:com.google.gwt.user.client.ui"
xmlns:ui="urn:ui:com.google.gwt.uibinder">
<gwt:HTMLPanel>
<div id="avmenu">
<h2 class="hide">Menu:</h2>
<ul>
<li>Welcome!</li>
</div>
</gwt:HTMLPanel>
</ui:UiBinder>
As an aside, in this example HTMLPanel adds a DIV of its own to the DOM, making the second div a bit redundant. Unfortunately, widgets in gwt don't have an easy way of setting the ID attribute from templates, so you're stuck with the second div unless you want to switch your #avmenu selector to .avmenu
Post how you are building menu in GWT. You are probably not using anchors inside your labels so your :hover styles are obviously not working.
I want to override my label color so redfined it one of the css in application using .gwt-label class. However at one specific location in the application, I need a different color. So I did the overriding the css style class in the UI binder of that class using #external
<ui:style field='otherStyle'>
#external .gwt-Label;
.gwt-Label { color: #fff; }
</ui:style>
It works fine but the moment I access this page in the browser, all the labels style take the effect of above style.
Any clue would be helpful.
Thanks in advance
I recommend you use a different style name, and add it to all of the elements you want to be a different color. You can't selectively choose which version of a single css class to use on different elements.