In jQuery, we can do
JQuery('.someStyle')
.css({"background", "red"})
to directly change the CSS property in style.
In Angular 2+, we can use [style.<property>] to manipulate, is there an option to directly manipulate the style sheet?
Angular offer template reference variable like this. Here #textCont is a template variable which can be passed to component and it can be used to add styles
<div #textCont> I wil change color on click<div>
<button type="button" (click)="changeColor(textCont)">Click</button>
In component
changeColor (elem){
elem.style.color="red"
}
DEMO
Even with the jQuery snippet you posted you don't manipulate the stylesheet, only the CSS properties of the object representing the DOM element.
Why would you want to manipulate the stylesheet directly? You would have to modify it before the browser parses it - before it is sent from server to client. This is hardly desirable.
What you are probably looking for is just a way how to change styles of your DOM element dynamically.
There are many ways how to achieve that with Angular ranging from injecting ElementRef (object providing access to component's host element) to your component's constructor or using Renderer2 in order to change the styles directly on the DOM element, to templating (like the [style.<property>] you have mentioned) or even Angular Animations.
Just fixed a small bug from #brk here. In Angular 13+ you may use:
<div #textCont> I wil change color on click</div>
<button type="button" (click)="changeColor(textCont)">Click</button>
And in Component more "strict typing"
changeColor(elem: { style: { color: string } }) {
elem.style.color = 'red';
}
Related
I have page index.html which includes file styles.css ( .foo{width:100%; ..... and other styles} )
via
<link href="styles.css">
And also this page includes svelte application
Svelte application has component with same class name .foo
<div class="foo"></div>
<style>
.foo{background-color:red;}
<style>
Svelte render it into something like this
<input class="foo svelte-12sas231dad">
Is there any method to protect my component's input from outer css ?
For example something to make
<input class="foo-svelte-12sas231dad">
without outer .foo class or may be another decision ?
The best solution is to not use global styles that accidentally apply where you do not want them to. I.e. remove the rules or use very specific class names that will not accidentally be used in components. Everything else is just a workaround to a fundamental problem you will run into again.
Given that Svelte adds classes with hashes you could target the element using a different method, e.g. just the tag type (input) or some data attribute.
As far as I know the only way to really isolate the element from styles would be adding an iframe which is far from ideal.
Are you using Sveltekit?
Perhaps you could use the The CSS !important Rule in your Svelte component styles.
Better yet, why not just change the class names?
For my current project I need to pass html (and styles) to puppeteer to generate a pdf from it.
I am accessing the html by using $ref.export.$el.innerHTML but how can I access the style? My workaround until now was to create a div that contains the same style attributes so I can access it as a ref aswell.
It is important to keep the original css syntax to be able to build html out of it afterwars. I also need to get the whole style for the component, not just for single elements.
First you need to access the ref and then you just need to access styles directly or get computed styles.
template
<!-- vm.$refs.p will be the DOM node -->
<p ref="p">hello</p>
Now you could access styles via this.$refs.p.style. If you want computed styles you would need helper function as in the example below.
script
methods: {
getStylesFromRef() {
// return this.$refs.p.style if you have style attributes
// following line for computed styles
return window.getComputedStyle(this.$refs.p)
}
}
I solved the issue by using <component> in my template with is="style", that way it is not removed during compile https://stackoverflow.com/a/57331310/8773697
I have an use case which requires me to style an angular component several different ways. I am building seperate components (buttons, lists etc..) for other developers to use for their respective brand. For exampe, the same angular component could be used in 4 different sites (thus the component is exported as a module), but all sites require different css for this component.
What does angular 2/4 cli offer to accomadate this ?
You have several options :
1. Stay very basic with your template
Sometimes, you can do the job with only one DOM node. Build a VERY basic template which can be placed everywhere without affecting the DOM or the styling, and let your collegues create the rest of the template. Thus, the component will not depend on your template, your class names or any styles you would have created otherwise.
Of course, this is kind of an extreme solution :) !
2. Build your component as a wrapper with internal logic
Suppose you need to create a button. Instead of creating a template with a button element, you could also create a div element which contains all the logic you need (a (click) event handler for exemple). This element is going to wrap a button provided by your collegues through transclusion. See below a possible custom-button component template :
<div (click)="handleClickEvent($event)">
<ng-content></ng-content>
</div>
In the parent component you may imagine to have this :
<custom-button>
<button class="btn btn-primary">
<i class="fa fa-chevron-right"></i>
</button>
</custom-button>
3. Use a classic html/css method
Give a template to your component and add class names to the DOM nodes in a way your collegues will be able to style them with a basic CSS.
It will be easy for you to prepare the component, but your collegues may be blocked by the names you choosed or the way the nodes are nested.
4. Give an entry point to provide styles used by the component template
For this, you will need an #Input() variable.
#Input() customStyles: any;
The variable will be provided to a HTML node through [ngStyles].
<button [ngStyle]="customStyles">Send</div>
The customStyles will necessarily be an object of a specific format (see official documentation here).
In the parent template, you could provide the styles like this :
<custom-button [customStyles]="{'max-width.px': widthExp}"></custom-button>
The problem here is that you have to provide as much variables (entry points) as you need to style all DOM nodes of your template...
5. Give an entry point to provide a class
Like before, a variable holds a value provided by your collegues in the parent template. Here, you expect a string to be provided, corresponding to a class name.
#Input() customClass : string;
In your template, you are going to add this custom class to the outer div
<div class="someClass {{ customClass }}> <!-- Outer div -->
<!-- Some DOM elements -->
</div>
Then, your collegues will be able to provide a class and to style all children elements in a CSS file according to the structure you create.
.bigButton {
height: 500px;
width: 1000px;
}
.bigButton > div {
padding: 100px;
}
.bigButton:hover > div {
// ...
}
In the parent template :
<custom-button [customClass]="'bigButton'"></custom-button>
I am using [innerHTML] binding to get some HTML content into a div, with a sanitizing pipe as described here.
I also need to be able to update the styles dynamically based on user input (font size, for example). I have been using [ngStyle] for other elements, but [ngStyle] does not seem to play well with [innerHTML]. The user can update the fontSizeVar, and the correct CSS can be found in the browser inspector, but the size of the [innerHTML] bound content never changes. Thoughts?
Template:
<div class='content'
[ngStyle]='{ "font-size": fontSizeVar }'
[innerHTML]='description | safeHtml'>
</div>
Thanks for the help, I wanted to leave an answer in case anyone else runs into this issue.
I had a stylesheet providing initial styles for the [innerHTML] bound content. [ngStyle] applies to the parent element, and will NOT override the styling of the child element if it is set explicitly. Removing the styling for the child element allowed the inheritance to work correctly, fixing my problem.
Thanks again!
Question:
In Web Components specification, when you want to read elements within a Light-DOM from the template the <content select></content> element can be used. But, how can this information be retrieved from the javascript code of the component?
Example:
<wc-timer>
<wc-timer-title>I want to read this from JS</wc-timer-title>
</wc-timer>
Thanks in advance, Javier.
Remember that this inside of your prototype methods refers to the element itself. IOW, just like you could do element.innerHTML or element.firstChild you can write this.innerHTML or this.firstChild.
Simple mode:
domReady: function() {
console.log(this.textContent);
}
http://jsbin.com/bociz/2/edit
This gets more complicated if you are using <content> to project nodes through multiple levels of Shadow DOM. In this case, you will need to use getDistributedNodes api of the <content> node itself.
Before getting into that, I suggest you start with the simple version, and ask a follow up question if you get into trouble.
Use this, for accessing lightDOM and
use this.shadowRoot to access shadowDOM
I have no idea what the template renders out as to the dom, but maybe you can try this:
//jQuery
$('wc-timer-title').text();
//Plain
document.getElementsByTagName("wc-timer-title")[0].innerHTML;
You should be able to use /deep/, it is being deprecated but there is no date as to when that will happen.