I want to style element in javascript easily but this function doesn't work
const addStyles = function (el, styles) {
Object.assign(el.style, styles);
}
You need to get the element first, then access the style property (it's a string) and set your CSS there.
Here's an example. As you can see the text is black and there is no CSS, however, with the javascript line I can make it red.
function addStyles(element, style) {
element.style = style;
}
const myElement = document.getElementById("myText");
addStyles(myElement, "color: red; font-size: 25px;");
<p id="myText">Some text<p>
Related
I've a div
<div class="display-container"></div>
Inside this div i want to append some text using a JavaScript event listener
const calculatorDisplay = document.querySelector(".display-container")
function appendNumber(number) {
calculatorDisplay.append(number)
}
// number event listener
one.addEventListener("click", () => {
calculatorDisplay.append(1)
})
it work perfecly, but the problem here is that the background color of the display-container div is black, and the default color for string is black, so, how do i change the color of an appended string?
i've already tried using the style tag, but that does not work, i've tried using fontcolor() too, but that too doesn't worked.
I've noticed that the appended string have an id of #text, but i cannout use it if i try.
Define css class
<style>
.colored-text {
color: red;
}
</style>
And then create span element with colored-text class and append it
// number event listener
one.addEventListener("click", () => {
const newSpan = document.createElement('span');
newSpan.classList.add('colored-text');
newSpan.textContent = 1;
calculatorDisplay.append(newSpan);
})
BTW. why are you defining appendNumber function and not using it?
There are several ways to achieve this.
javascript
const calculatorDisplay = document.querySelector(".display-container")
// changing the color to red
calculatroDisplay.style.color = 'red';
// it accepts also Hex colors
calculatorDisplay.style.color = '#FF5733'
// OR rgb
calculatorDisplay.style.color = 'rgb(255,0,0)
CSS
It is also possible to append a classname to your div. Like this you could
make the code probably more reusable and may apply more styles than just colors in a simple manner. (There are multiple ways to include CSS in your html, google it^^ )
// within in the <head> tag in the html add a <style> tag.
<html>
<head>
<style>
.red-color {
color: red
}
</style>
</head>
<body>
<!-- ..... --->
</body>
</html>
In the code you can now add a classname using element.classList.add() OR element.classList.remove() to remove classes!
function setRedColor(el) {
el.classList.add('red-color')
}
function removeRedColor(el) {
el.classList.remove('red-color')
}
const calculatorDisplay = document.querySelector(".display-container")
setRedColor(calculatorDisplay)
// ...
removeRedColor(calculatorDisplay)
Note that the element.classList API generally does not allow classnames with a whitespace in it. So if you have mutliple classes you have to apply them one by one or you'll run into an error.
Feel free to leave a comment
So In javascript you can do things like
document.querySelector('html').style.filter = 'invert(100%)'
Which Inverts colors on the entire webpage
but is there anyway to use
document.querySelector('html').style.pointer = 'something'
or a way to
add a css rule or something to the document?
example
you have an element like this
hello
then js gives an class
hello
then js adds a css rule?
.why {}
You could write to the document using document.write
document.write(`
<style>
#text {
color: red;
}
</style>`)
<h1 id='text'>Hello</h1>
Or, you can also create an element and append it to the document
let style = document.createElement('style')
style.innerHTML = `
.text {
color: red;
}
`
document.body.appendChild(style)
<h1 class='text'>Hello</h1>
You can add a css class to specific element with (and then create the styles from the css file):
[NameOfTheElement].classList.add("mystyle")
This will work for the document:
document.querySelector('html').classList.add('new-class');
This will work for the body:
document.querySelector('body').classList.add('new-body-class')
There are a few ways.
If you already have styles defined for a certain class within your stylesheet, you can do what Erasmo said above:
element.classList.add('className');
You can also use:
element.style.color = 'white';
Or add a style attribute to the element:
element.setAttribute('style', 'color: white; background-color: green;');
I am trying to move an element from the light DOM to the shadow DOM, but when I do so the styling isn't copying over. I tried to fix this by setting the newElement.style = window.getComputedStyle(elem), but this hasn't seemed to work. The styles should be:
.card {
color: #ff0;
font-size: 3rem;
font-weight: 600;
border: 3px solid blueviolet;
background-color: greenyellow;
}
but the styles don't apply and when I print the getComputedStyle() to console what I see is:
all the values are empty
However, when I loop through the properties of getComputedStyle() with .getPropertyValue() like so:
for(let property of style){
console.log(`property: ${property}, value: ${style.getPropertyValue(property)}`);
}
what I get in the console is:
the correct values
So I'm confused as to why getComputedStyle() doesn't contain the values, but using getComputedStyle().getPropertyValue() returns the correct values. I'm sure I'm missing something obvious, as I couldn't find another post about this anywhere.
Any help would be greatly appreciated, thanks in advance.
EDIT: I've taken the code provided by Danny below and modified it to better show the issue I'm facing:
<style>
.card {
color: yellow;
background: green;
}
</style>
<my-element>
<div class="card">lightDOM reflected to shadowDOM</div>
</my-element>
<script>
customElements.define("my-element", class extends HTMLElement {
constructor(){
super().attachShadow({mode:"open"}).innerHTML = ``;
}
connectedCallback() {
setTimeout(() => { // wait till innerHTML is parsed
let card = this.children[0]; // Get the light DOM Card element
this.shadowRoot.appendChild(card.cloneNode(true)); // Append it to the shadowDOM
let style = window.getComputedStyle(card); // Get style of the Light DOM Card
this.shadowRoot.querySelector('.card').style = style; // Set the ShadowDOM card style equal to the Light DOM Style
console.log(style);
console.log(style.color); // yellow = rgb:255,255,0
console.log(style.background); // green = rgb:0,128,0
card.remove(); // Remove the card from the Light DOM to prevent duplication
})
}
})
</script>
Notice that the styling above doesn't apply even though it seems to be exactly as the docs specify:
"The returned object is the same CSSStyleDeclaration type as the object returned from the element's style property. However, the two objects have different purposes:
The object from getComputedStyle is read-only, and should be used to inspect the element's style — including those set by a element or an external stylesheet.
The element.style object should be used to set styles on that element, or inspect styles directly added to it from JavaScript manipulation or the global style attribute."
https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle#description
From MDN Documentation:
The Window.getComputedStyle() method returns an object containing the values of all CSS properties of an element, after applying active stylesheets and resolving any basic computation those values may contain. Individual CSS property values are accessed through APIs provided by the object, or by indexing with CSS property names.
It's stated that you need to use API functions, such as getPropertyValue() to get the value of it.
Ref: https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle
If you want to print all of the CSS styles from a specific element you may just iterate all the attributes like this:
function dumpCSSText(element){
var s = '';
var o = getComputedStyle(element);
for(var i = 0; i < o.length; i++){
s+=o[i] + ': ' + o.getPropertyValue(o[i])+';\n';
}
return s;
}
var e = document.querySelector('.card');
console.log(dumpCSSText(e));
.card {
color: #ff0;
font-size: 3rem;
font-weight: 600;
border: 3px solid blueviolet;
background-color: greenyellow;
}
<div class="card"></div>
property style is read-only so you can't assign anything to it;
(I stand corrected per comments; you can assign a value, but it
will override all values)
The innerHTML of Custom Elements is not parsed yet when the connectedCallback fires. So getting styles of its children with getComputedStyle is an operation on non-existing elements.
If you reflect the lightDOM contents to a <slot> in shadowDOM, there is no need to copy styles as the styling from lightDOM is reflected
<style>
.card {
color: yellow;
background: green;
}
</style>
<my-element>
<div class="card">lightDOM reflected to shadowDOM</div>
</my-element>
<script>
customElements.define("my-element", class extends HTMLElement {
constructor(){
super().attachShadow({mode:"open"}).innerHTML = `<slot></slot>`
}
connectedCallback() {
setTimeout(() => { // wait till innerHTML is parsed
let card = this.querySelector(".card"); // in lightDOM!
let style = window.getComputedStyle(card);
console.log(style.color); // yellow = rgb:255,255,0
console.log(style.background); // green = rgb:0,128,0
})
}
})
</script>
More reading:
https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot
::slotted CSS selector for nested children in shadowDOM slot
wait for Element Upgrade in connectedCallback: FireFox and Chromium differences
I'd like to remove the ugly focus outline on an input button in firefox. I've tried adding ::-moz-focus-inner {border:0;} as style in my html, which works initially, but not when button elements are re-created via javascript.
I've tried:
cell.style.mozFocusInner.border = "0";
cell.style["-moz-focus-inner"] = "{border:0}";
cell.style["-moz-focus-inner"]["border"] = "0";
etc.
In general, how do I "map" css to javascript?
According to the CSS property to IDL attribute algorithm, a -moz-focus-inner would be camelCased to MozFocusInner. So you could use one of
element.style.MozFocusInner = value;
element.style.setPropertyValue('-moz-focus-inner', value);
element.style.setProperty('-moz-focus-inner', value);
element.style.setProperty('-moz-focus-inner', value, '!important');
But there is a big problem: -moz-focus-inner is not a CSS property, is a pseudo-element.
Given an element, you can read the computed styles of its pseudo-elements via getComputedStyle:
getComputedStyle(element, '::-moz-focus-inner').borderTopWidth; // 1px
However, you can't set them directly. If you want to do that, you can:
Conditionally set the desired styles in a stylesheet, and use JS to trigger that condition whenever you want. For example, add a class.
document.getElementById('enable').addEventListener('click', function() {
document.getElementById('target').classList.remove('no-focus-inner');
});
document.getElementById('disable').addEventListener('click', function() {
document.getElementById('target').classList.add('no-focus-inner');
});
.no-focus-inner::-moz-focus-inner {
border: none;
}
<ol>
<li><button id="enable">Enable inner outline</button> or <button id="disable">Disable inner outline</button></li>
<li>Press Tab key</li>
<li><button id="target">Focus me to check if I have inner outline</button></li>
</ol>
Create a new stylesheet with the desired rulesets, and append it to the document.
var styleSheet = document.createElement('style');
styleSheet.textContent = '#target::-moz-focus-inner { border: none; }';
document.getElementById('enable').addEventListener('click', function() {
if(styleSheet.parentNode) document.head.removeChild(styleSheet);
});
document.getElementById('disable').addEventListener('click', function() {
document.head.appendChild(styleSheet);
});
<ol>
<li><button id="enable">Enable inner outline</button> or <button id="disable">Disable inner outline</button></li>
<li>Press Tab key</li>
<li><button id="target">Focus me to check if I have inner outline</button></li>
</ol>
Maybe this works without javascript: https://css-tricks.com/forums/topic/button-padding-issue/
::moz-focus-inner is a pseudo-element. In this link are several ways how to modify pseudo-elements dynamically (with javascript) http://pankajparashar.com/posts/modify-pseudo-elements-css/
cited from http://pankajparashar.com/posts/modify-pseudo-elements-css/ :
<p class="red">Hi, this is a plain-old, sad-looking paragraph tag.</p>
.red::before {
content: 'red';
color: red;
}
Method 1
Write separate classes attached with pseudo element for each style and then using JavaScript or jQuery toggle between these classes.
.green::before {
content: 'green';
color: green;
}
$('p').removeClass('red').addClass('green');
...
Common css-styles (not pseudo-elements) can be modified using javascript like this:
cited from https://www.kirupa.com/html5/setting_css_styles_using_javascript.htm :
Every HTML element that you access via JavaScript has a style object. This object allows you to specify a CSS property and set its value. For example, this is what setting the background color of an HTML element whose id value is superman looks like:
var myElement = document.querySelector("#superman");
myElement.style.backgroundColor = "#D93600";
To affect many elements, you can do something as follows:
var myElements = document.querySelectorAll(".bar");
for (var i = 0; i < myElements.length; i++) {
myElements[i].style.opacity = 0;
}
In a nutshell, to style elements directly using JavaScript, the first step is to access the element. I am using the querySelector method to make that happen. The second step is just to find the CSS property you care about and give it a value. Remember, many values in CSS are actually strings. Also remember that many values require a unit of measurement like px or em or something like that to actually get recognized.
New to JavaScript and CSS and I am trying to give the user a button that will change the background color of a game board (set up with div) randomly when pressed.
<style type="text/css">
div.conway {
overflow: hidden;
font-family: courier;
float: left;
width: 800px;
height: 488px;
background-color: green;
font-size: 10px;
color: gold;
}
</style>
and inside my script tag I have the following:
function getRandomColor() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++ ) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
my.changeBackgroundColor = function () {
document.getElementById(conway).style.background-color = getRandomColor();
}
But the DOM is not letting me assign the new color. What am I doing wrong?
background-color should be backgroundColor:
document.getElementById(conway).style.backgroundColor = getRandomColor();
or this is allowed as well:
document.getElementById(conway).style["background-color"] = getRandomColor();
In JavaScript, you can refer to an object property using dotted notation and a property name literal (obj.foo), or using bracketed notation and a property name string (obj["foo"]). A property name literal has to be a valid JavaScript identifier, and obviously you can't have a - in an identifier, it looks like a minus sign. So instead, camelCase is used where hyphens would normally be in the style object.
Side note: You haven't shown your HTML, or the content of your conway variable, but I assume you have an id on the element in question, and that the conway variable contains that id. E.g.:
<div id="cell23">...</div>
and
conway = "cell23"
Try using backgroundColor instead off of style.
JS is treating - as the minus operator.
The problem is that you are trying to access the DOM element by ID using document.getElementById(conway) but conway is a class. So you either have to give the targeted div an ID or use document.getElementsByClassName('conway'); which will effectively get all of the element that have a class name conway. Not sure if that is what you want.
You are calling the wrong property. It should be:
my.changeBackgroundColor = function() {
document.getElementById(conway).style.backgroundColor = getRandomColor();
}
Here is working js fiddle example
You had few problems within your code,
Line:
document.getElementById(conway).style.background-color = getRandomColor();
Should be defined as: (see how backgroundColor is written and usage of "" for id).
document.getElementById("conway").style.backgroundColor = getRandomColor();
Also, remember to apply your styles to id element (can't see whether your div has a class conway defined or not.)
div#conway { .. }
After that it works great.
I also recommend that you check CSS properties reference which lists formats used for giving css attributes using javascript. In other words, the problem which you had.!
Cheers.