For example,
(If) I have this 2d editor in HTML form:
and I have a css file named "filter" with code:
monochrome {
filter: grayscale(var(--value, 100%)); --value:100%;
}
What are the methods to apply the "monochrome" filter to the editor's Dragon when placing it(The dragon sprite) onto the canvas?
<link rel="stylesheet" type="text/css" href="monochrome.css">
if (data[Blocks].id === "dragon") {
*What should I write here in order to apply the css filter (only to the dragon sprite, when placing?*
}
The first step is turning the CSS monochrome definition into a class. This is simply done by prepending a dot prior the name e.g.
.monochrome {
filter: grayscale(var(--value, 100%));
}
Defining it this way makes it reusable by multiple HTML elements - as your Dragon might not be the only element which you want to apply the filter to.
As we have a CSS class now we can apply it to individual objects by calling either
theObject.classList.add("monochrome");
or
theObject.classList.remove("monochrome");
while add / remove as it's name implies adds or removes the CSS class given in quotes.
But how do we get a reference to theObject?
If you've given your HTML elements an unique id using it's id property it's quite easy:
document.getElementById("id")
Be careful though - it's something different than the id you've mentioned in your post.
Here's an example:
document.getElementById("monochromeButton").addEventListener("click", function() {
document.getElementById("dragon").classList.add("monochrome");
});
document.getElementById("removeButton").addEventListener("click", function() {
document.getElementById("dragon").classList.remove("monochrome");
});
.monochrome {
filter: grayscale(var(--value, 100%));
}
<button id="monochromeButton">
monochrome
</button>
<button id="removeButton">
remove filter
</button>
<br>
<img id="dragon" src="https://picsum.photos/id/237/200/140">
Related
I'm trying to create a webpage where there are three working buttons that are labelled "Red", "Green", and "Blue". When the user clicks on one of the buttons, the entire webpage should change to the color of the specific button that was clicked.
This is what I have so far, but I'm pretty sure I'm doing something wrong:
function myFunction() {
document.getElementById("H1").style.color = "#ff0000";
}
<h1 id="H1">H1</h1>
<button type="button" onclick="myFunction()">Set H1 to Red</button>
We begin with creating three radio buttons named red, green, blue inside the form tag and use attribute named on Click and assign value document. bgcolor=color name to it.
There is only one problem here that you changed color but you want to change background color.
Hope this will help you.
function myFunction() {
document.body.style.backgroundColor = "#ff0000";
}
onClick the button will invoke the changeColor function which will take the innerText
of the button as style value and set it as background color of the body.
function changeColor (element){
document.body.style.backgroundColor = element.innerText
}
console.log(document.body.style.backgroundColor)
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<button onclick="changeColor(this)" >Red</button>
<button onclick="changeColor(this)" >Green</button>
<button onclick="changeColor(this)" >Blue</button>
</body>
</html>
You can also use class or id selector to select the element instead of using tag name.
const element = document.getElementsByClassName(".class")
In this case the element will be an array of nodes that have the same class. You can use forEach loop to trigger color change on all of them.
or use an Id if the target is a single element.
const element = document.getElementById("id")
You can also use onclick event listener to change the color.
First the "problems," which I'm not convinced are problems since clicking the <button> does exactly what the <button> says – in its text – that it will do. However:
function myFunction() {
// as the button-text implies this JavaScript retrieves
// the element with the id of 'H1', and updates its
// CSS - via the inline style element - to the colour
// of '#ff0000' (or '#f00'), which is red.
document.getElementById("H1").style.color = "#ff0000";
}
<h1 id="H1">H1</h1>
<!-- Obviously you know that this element is intended to set
the colour of the <h1> element, given the text of the
<button>; also you're using an inline event-handler
(the 'onclick' attribute) to bind a function to an event,
which is considered bad practice due to the obtrusive
nature of the event-binding, and difficulty of updating
function calls: -->
<button type="button" onclick="myFunction()">Set H1 to Red</button>
To do as you ask, and instead set the background-color of a given element, we must:
retrieve that element in the JavaScript,
update the correct – background-color – property,
find a means by which the <button> can "communicate" the correct value to which that property must be set, and ideally
use unobtrusive JavaScript to bind the function to the 'click' event.
To do that:
// assigning a meaningful name to the function
// in order to make future maintenance easier:
function setBackgroundColor(evt) {
// retrieving the element we wish to style:
const body = document.querySelector('body')
// accessing the style interface, and
// updating the background-color, via the
// JavaScript camelCased property-name:
body.style.backgroundColor = evt.currentTarget.value;
}
// retrieving the <button> elements:
const buttons = document.querySelectorAll('button');
// iterating over that NodeList of <button>
// elements, using NodeList.prototype.forEach():
buttons.forEach(
// using an Arrow function, passing in a reference
// to the current Node of the NodeList over which
// we're iterating. Here we use the
// EventTarget.addEventListener() method to bind the
// setBackgroundColor() functiona as the 'click'
// event-handler when the node is clicked (also fired
// on keyboard navigation if the user hits spacebar
// or enter):
(node) => node.addEventListener('click', setBackgroundColor)
)
<h1 id="H1">H1</h1>
<!-- here we're adding a "value" attribute to hold
the colour to set; we're using a colour-name
('red'), a hexadecimal ('#87cefa'), and
a hsl() ('120deg 93% 80%') value as the colour: -->
<button type="button" value="red">Red</button>
<button type="button" value="#87cefa">Blue</button>
<button type="button" value="hsl(120deg 93% 80%)">Red</button>
There is, of course, an alternative and that's to use a colour-picker <input>, which allows the user to pick any colour of their choice and simply pass the chosen value to the function:
// assigning a meaningful name to the function
// in order to make future maintenance easier:
function setBackgroundColor(chosenColor) {
// caching the <body> element:
const body = document.querySelector('body');
// updating the background-color via the
// 'style' interface:
body.style.backgroundColor = chosenColor;
}
// retrieving the <input> element with a type-attribute
// equal to "color":
const input = document.querySelector('input[type=color]');
// using EventTarget.addEventListener() to use the anonymous
// function to call the setBackgroundColor() function, passing
// the value of the evt.currentTarget node (the color <input>)
// as the argument:
input.addEventListener('change', (evt)=> setBackgroundColor(evt.currentTarget.value));
<h1 id="H1">H1</h1>
<input type="color">
References:
Arrow functions.
CSSStyleDeclaration.
document.querySelector().
document.querySelectorAll().
EventTarget.addEventListener().
I would like to extend the native button element but I am not sure how to add styling. In Google's example here they don't use a template so the fancy-button custom element itself is the button, rather than adding a template and shadow DOM containing a button element. It seems to defeat the object of extending a native element if I just add a button directly to the shadow DOM, but I don't know how to style and extend native element. How can I create a custom element which is simply the native button element extended to have a red background?
var style = `button { background-color: red; };
class FancyButton extends HTMLButtonElement {
constructor() {
super();
}
customElements.define('fancy-button', FancyButton, {extends: 'button'});
since you don't have shadowDOM involved you can use global CSS
you can set styles in the connectedCallback: this.style.background='red'
you can dynamically create a STYLE tag with unique identifier scoping your element
See JSFiddle for all 3 examples: https://jsfiddle.net/WebComponents/gohzwvL4/
Important is the notation for your Customized Built-In Element
Correct : <button is="fancy-button></button>
InCorrect: <fancy-button></fancy-button> (this is Autonomous Element notation)
.
Firefox pitfall:
The INcorrect notation works in Firefox , but not in Chrome & Opera
Firefox processes Extended Built-In Elements with Autonomous Element notation
but only for elements created in the DOM prior to definition:
This
<fancy-button>Hello Fancy Red Button #1</fancy-button>
<script>
class FancyButton extends HTMLButtonElement {
constructor() {
super();
}
connectedCallback() {
this.style.background = 'red';
}
}
customElements.define('fancy-button', FancyButton, { extends: 'button' });
</script>
<fancy-button>Hello Fancy Red Button #2</fancy-button>
is displayed in Firefox as:
any number of Custom Elements before the SCRIPT tag are colored!
When the <SCRIPT> is moved into the <HEAD> Firefox won't color any background
When the script is executed after the onload event all buttons are colored
This is non-standard behaviour!
In order to avoid adding an extra is-icon class to each of my icon elements, such as this:
<style>
.is-icon { // Base styling of icon }
.icon-car { // specific car styling }
</style>
<span class="is-icon icon-car">car</span>
I am using this CSS to solve it:
<style>
span[class^="icon-"] { // base icon styling }
.icon-car { // specific car styling }
</style>
<span class="icon-car">car</span>
<span class="icon-cat">cat</span> ETC...
My question is: does span[class^="icon-"] css selector is expensive? and which one is a better practise? My understanding is Substring Matching css attr selector is not a bad practise at all, it's just more of a preference. Please help me understand this.
I'm noot good in english, so the title may seem a bit odd.
I want to use css function attr() like this:
I mean i have a container <div> and an inner <div> that i want to have width depending on data-width attribute. For example this would be great, but this doesnt work:
<div class="container">
<div data-width="70%">
</div
</div>
.container {
width: 600px;
height: 200px;
}
.container div {
width: attr(data-width);
height: 100%;
}
Is there any noJS way to use attributes like that?
UPDATE: Guys convinced me that the JS is the only way to do this :)
That's not a big problem (but that's bad. CSS, why youre so illogical? Is the difference between content:attr(data-width) and width: attr(data-width) so big ?).
One of the guys had an idea to go through the all elements with jQuery.
That's ok, but it is very... local? Don't know how to say it in english.
Anyway, i remaked his code a little bit and here it is:
allowed = ['width','color','float'];
$(document).ready(function () {
$('div').each(function (i, el) {
var data = $(el).data(),style = '';
if (!$.isEmptyObject(data)) {
$.each(data, function (attr, value) {
if (allowed.indexOf(attr) != - 1) {
style += attr + ': ' + value + '; ';
}
})
if (style.length != 0) {
$(el).attr('style', style);
}
}
})
})
Idea is simple:
1. We suppose that style we want to add to an element is the only one. I mean there are no scripts that will try to add some other styles,
2. We create an array of allowed attribute names, we need to avoid using wrong names at the style attribute, for example style="answerid: 30671428;",
3. We go through each element, save its data attributes in an object, check if object is empty, and if not - check every attribute if it is allowed, create a string that contains all styles that we need, and - finally - add our style string to the element as the content of style attribute.
That's all, thanks everybody
I would not advise to use CSS alone since it will not allow you to do what you're looking for... instead use a scripting language (in my case jQuery) to accomplish this functionality for you like so: jsFiddle
jQuery
jQuery(document).ready(function(){
var dataElem; // to store each data attribute we come accross
jQuery('div').each(function(){ //loop through each div (can be changed to a class preferably)
dataElem = jQuery(this); //get the current div
if(dataElem.data('width')){ //make sure it exists before anything further
dataElem.width(dataElem.data('width')); //set the element's width to the data attribute's value
dataElem.css("background-color", "yellow");
}
});
});
HTML
<p>The links with a data-width attribute gets a yellow background:</p>
<div>
w3schools.com
</div>
<div class="me" data-width="50"> <!-- change value to see the difference -->
disney.com
</div>
<div>
wikipedia.org
</div>
Notes on the above:
each, data, width.
Instead of doing data-width, use a class attribute. An html tag can have mutliple classes separated by spaces, so if you wanted to be very precise, you could set up as many classes as you need. For instance:
<div class="w70 h100">
</div>
Then in your css:
.w70{
width: 70%;
}
.h100{
height: 100%;
}
And so on.
Is there any noJS way to use attributes like that?
No, you cannot use CSS to set the width of the element to it's data-width attribute. CSS does not allow for this as attr() is only currently available for the CSS content property which is only available on css pseudo elements (::before and ::after).
How can you achieve this with as little javascript as possible?
This is extremely easy to do using the native host provided DOM API.
Select the elements using Document.querySelectorAll().
Iterate the elements and apply the styles using Element.style which can be retrieved from the data-width attribute using Element.dataset
(Demo)
var items = document.querySelectorAll('#container div'), item, i;
for(i = 0; (item = items[i]); i++) item.style.width = item.dataset.width;
I'm creating a tumblr them and I have to write an external CSS file but I am having trouble editing the css style of the post elements.
This its structure:
<li class="post quote">
{other code}
</li>
The problem is that the class name has a space in it.
How would I create a CSS class to access this? And yes, I know I can just put a style attribute in the element tag but I was kind of hoping for another option.
The problem is that the class name has a space in it.
This is not possible in CSS. What you are doing is giving the element two classes.
You can address them such:
.post.quote { .... }
but in your case, it's probably better to use a valid separator like
post_quote
This element actually has two classes - it is marked with both the post class and the quote class. So, you can use the following selectors to access it:
// css
.post { ... } // elements with the post class
.quote { ... } // elements with the quote class
// jQuery
var postLis = $('.post');
var quoteLis = $('.quote');
You can also stack selectors to return all elements which meet all conditions in the selector, by including the different selectors together:
// css
.post.quote { ... } // elements with both the post and quote classes
// jQuery
var postAndQuoteLis = $('.post.quote');
This might work:
$('li').each(function() {
if($(this).attr('class').indexOf(" ")>-1) {
$(this).css('border','1px solid #ff0000')
}
}