I am trying to create a very low specificity css property using javascript. Just like !unimportant (which doesn't exists)
I don't know whether this is possible or not.
My reason to look for something like !unimportant is that I am writing a small javascript plugin. In which I want to add a default style to a element which should be later easily overriden by the user.
But if I write:
element.style.backgroundColor = "green";
The user will not be able to override the above style easily without using !important. So, I added a dynamic style tag by using the following code:
var style = document.createElement('style');
// WebKit hack :(
style.appendChild(document.createTextNode(""));
document.head.appendChild(style);
and then to the above code, I added a dynamic stylesheet using the following code:
var element = document.getElementById('main');
// To use attribute names to apply the styles
element.setAttribute('custom-el', '1');
var sheet = style.sheet;
var properties = "background-color: green;";
var elName = "[custom-el]";
if (sheet.insertRule) {
sheet.insertRule(elName + "{" + properties + "}", 0);
} else if (sheet.addRule) {
sheet.addRule(elName, properties, 0);
}
Now the background-color: green can be overriden by using the following code:
div.main {
background-color: red;
}
But as you can see in css, I used higher specificity to override background-color: green i.e div + .green.
But I want the overriden to happen even when user writes the following css:
.main{ /* Could be simple class name or id name or even tag name */
background-color: red;
}
Fiddle
This might seems to be a small issue. but it is a big problem for me. Please help.
I would simply write like this:
element.style.backgroundColor = element.style.backgroundColor || "green";
Where, if backgroundColor is undefined then it uses green as backgroundColor else it would take the backgroundColor from stylesheet.
Finally I got the answer..
document.head.insertBefore(style, document.head.children[0]);
I should just insert the dynamic stylesheet above already present stylesheets in the head tag.
Working Fiddle
Unfortunately, this is not working in any IE version. I am still looking for answer.
Related
I have this call to add HTML/CSS to an existing page:
let div = document.createElement('div');
div.style.zIndex = 9999999;
div.innerHTML = str; // some pre-defined HTML string
document.body.insertBefore(div, document.body.firstChild);
I am creating a Chrome Extension that helps developers. What's happening is that the above HTML is inheriting the existing CSS from developer's pages. I want the styling of the above HTML to be independent from the CSS/styling on the developer's page.
Is there a way to ignore all existing CSS on page? I'd like to basically create a "CSS sandbox".
I think one way to create such a sandbox, would be an iframe, but I am looking for a simpler way to do that.
Add a class to elements which you want to reset..and then apply all:unset to that class
The all CSS shorthand property sets all of an element's properties (apart from unicode-bidi and direction) to their initial or inherited values, or to the values specified in another style sheet origin.
...all:unset
Specifies that all the element's properties should be changed to their inherited values if they inherit by default, or to their initial values if not.(It will ignore all the user agent style too.)
Stack Snippet
let p = document.createElement('p');
p.style.color = "red";
p.innerHTML = "Hello"; // some pre-defined HTML string
p.classList.add("reset");
document.body.insertBefore(p, document.body.firstChild);
p {
background: black;
}
.reset {
all: unset;
}
Following up from
line break for d3 circle title tooltipText
the code is
svgContainer.selectAll("g.node").each(function() {
var node = d3.select(this);
var tooltipText = node.attr("name");
var tooltipText = node.attr("name").replace("\\n", "<br />");
if (tooltipText) {
node.select("circle")
.attr("data-html", "true")
.attr("title", tooltipText);
}
and I'd like to replace the .attr("data-html", "true") function with CSS formatting
css, not-working-1:
# g.node circle { data-html: true;}
css, not-working-2:
# g.node circle { html: true;}
both above 2 have "Unknown property name" error.
I'm wondering, what is the CSS equivalent to .attr("data-html", "true")?
Thank you very much.
CSS is (designed for) a simple mechanism for adding style to an HTML document.
The code you referred to actually mutates the DOM (in this case, the html-node).
On a side note: If you want to 'select' based upon that state in CSS, you could do.
html {
background: red;
}
html[data-something=true] {
background: green;
}
if then the JavaScript sets $('html').attr('data-something', 'true'); your CSS would be applied (from red background to green).
It doesn't have equivalent CSS property. CSS is the look and some behavior. data-html is an HTML5 styled attribute, which is used to store a data. You can add anything with data- prefix.
So you need to use a Javascript to add an HTML5 attribute.
I've been working with jQuery for a while, but now I want to write something in pure javascript and it's prooving to be challenging..
One of my biggest problems at the moment is that I haven't found a way to set/change styling for a class. This is not a problem for elements with id, but I want to change the styling for a group of elements with the same class and not just for one element with an id..
In jQuery I would just write:
$('.someClass').css('color','red')
Is there really no simple equivalence to this in pure js?
Try the following
var all = document.getElementsByClassName('someClass');
for (var i = 0; i < all.length; i++) {
all[i].style.color = 'red';
}
Note: As Cheery pointed out getElementsByClassName won't work in IE. The linked question has a nice way to work around this limitation
javascript document.getElementsByClassName compatibility with IE
I find it easier to use CSS variables. You can set the class to use a variable and then change that value in Javascript, thus changing the CSS.
If you style the class like:
:root {
--some-color: red;
}
.someClass {
color: var(--some-color);
}
Then you can change the variable's value in Javascript with
document.documentElement.style.setProperty('--some-color', '(random color)');
(random color) can then be anything that would be considered a valid CSS color (eg. blue, black, #626262, rgb(12, 93, 44))
Updating the value in JS automatically updates the page as well.
And of course, this can be done with any property, not just color. Here is an example that changes the padding of a class:
CSS
:root {
--some-padding: 12px;
}
.someClass {
padding: var(--some-padding);
}
Javascript
// Set padding to 15px
document.documentElement.style.setProperty('--some-padding', '15px');
// Set padding to 5rem
document.documentElement.style.setProperty('--some-padding', '5rem');
// Set padding to 25%
document.documentElement.style.setProperty('--some-padding', '25%');
Useful example: toggle dark / light mode:
(How to use css properties to dynamically set css properties)
// set to light mode:
document.documentElement.style.setProperty('--bg-color', getComputedStyle(document.documentElement).getPropertyValue('--bg-color-light'));
// set to dark mode:
document.documentElement.style.setProperty('--bg-color', getComputedStyle(document.documentElement).getPropertyValue('--bg-color-dark'));
With the respective css:
:root {
--bg-color: black;
--bg-color-light: white;
--bg-color-dark: black;
body {
background-color: var(--bg-color);
}
Sources
How to declare and use CSS variables: https://www.w3schools.com/css/css3_variables.asp
How to update a CSS variable in JS: https://css-tricks.com/updating-a-css-variable-with-javascript/
var sheet = document.createElement('style')
sheet.innerHTML = ".someClass {color: red;}";
document.body.appendChild(sheet);
What you want to change is the style sheet, I guess? Thats possible in Javascript, see
Quirksmode: Change CSS
Totally Pwn CSS with Javascript (in Internet Archive)
Is the only way to change a style to do it per-element in JavaScript? (possible duplicate)
I'm afraid there is no library for that, I really would like to see one...
var all = document.getElementsByClassName('someClass');
for (var i = 0; i < all.length; i++) {
all[i].className += " red";
}
For better coding style add another class to the elements with the code above and then use CSS to change the color of all elements like this:
.red {
color:red;
}
You can use selector library, for example Sizzle: http://sizzlejs.com/ but if you want pure JS that I guess you are stuck with getting all the elements, and then programatically "handpicking" the ones that have classes you are interested in using RegEx like this for example:
This is an equivalent of your JQuery oneliner:
for( i in document.all) document.all[i].className && /\bpost-text\b/g.test(document.all[i].className) && (document.all[i].style.color = "red")
:)
If you don't need it in one line you can make it faster (and much more readable):
var myClassName = "someClass";
var regexp = RegExp("\\b"+myClassName+"\\b/g");
var elements = document.all;
for( i in elements){
var this_element = elements[i];
if(regexp.test(this_element.className){
this_element.style.color = "red";
}
}
If "for( i in object)" doesn't work for you, just use classic for loop "for(var i = 0; i < elements.length; i++)".
It could be 'beautified' a bit with the use of some slightly more advanced JS concepts (array function mappings, folding and such), which JS version are you coding agains? I guess it's not ECMA Script 5, right?
Also, check out this question/answer Get All Elements in an HTML document with a specific CSS Class
I have a div and when I mouse over it I want to change the background (and possibly other properties). I can do it by calling el.style.backcolor = "", but is there a way I can add another CSS style to it then remove it later? Like style += mouseOverStyle and then style -= mouseOverStyle. That way I could select the properties to change in the CSS instead of in the JavaScript code.
EDIT: I may want to apply the new style in other situations, not just mouseover, so #div:hover isn't really a general solution. What I'm really asking is is there something like style.add("style") and style.remove("style")?
If I understood you correctly, you're asking to change the background when you hover your div element?
This is easily done via CSS, no Javascript or other codes are necessary!
#myDiv
{
background-color: #f00;
}
#myDiv:hover
{
background-color: #00f;
}
Of course you can change other styles too, you don't need to add another class to change one or more styles.
Hope that helps :)
Just add or remove CSS classes when needed.
Adding:
yourElement.className += ' my_class';
Removing:
yourElement.className = yourElement.className.replace(/\bmy_class\b/, '');
With jQuery you can use addClass, removeClass and toggleClass methods (see the docs).
You could try using multiple :hover pseudo selectors:
div.style1:hover { background: red }
div.style2:hover { background: yellow }
Then use javascript/jquery to switch between html class attributes
I would recomendate you to use a JS library, such as jQuery. In jQuery it is simple like that:
http://api.jquery.com/addClass/ together with the mouseover event handling http://api.jquery.com/mouseover/.
function changeStyle()
{
document.getElementById("elementID").style.color="green";
}
after the .style. you should paste the css attribute you want to edit.
If you're wanting to use js, change the properties on the user event.
onmouseover : el.style.background = "blue";
onmouseout : el.style.background = "red";
If you want to add more properties as time goes along just throw it in a function
function onMouseOverFunction () {
el.style.background = "blue";
el.style.color = "blue";
el.style.font-size= "1em";
}
I'm making a widget that will be added to external websites, and I have made a page that generates css for them to style it (text color, background color, font size, etc). I end up with a textarea filled with css for them to copy/paste to their website.
Is there a way to add this css to the current page in order to have a live preview?
If you want to add CSS as text
var style = document.createElement('style');
style.innerHTML = 'content';
document.head.appendChild(style);
If you want to add a CSS file
var link = document.createElement('link');
link.setAttribute('rel', 'stylesheet');
link.setAttribute('href', 'css/my.css');
document.head.appendChild(link);
I have traditionally appended a <style> block when doing elements.
var style_rules = [];
style_rules.push("#" + myElemId + " { /* Rules */ } ");
/* ... */
var style = '<style type="text/css">' + style_rules.join("\n") + "</style>";
$("head").append(style);
An important thing to note is that because you don't know what any of the existing styles is, or what id's might conflict on the page, it's very useful to keep track of your id's inside your JavaScript application, then using those to populate the injected <style> block. I also tend to run my names through a prefix function to ensure that the generic names of wrapper, and unit do not conflict (they are turned into something like myunique_wrapper and myunique_unit.
Incorporating a basic CSS reset like #myWrapper {margin: 0; padding: 0} can be a decent starting platform for building your own custom styles.
Addressing your unique case, a live preview so to speak, I would designate a div with standard elements. Then when they click "update" read in the rules and append them to the head. If you want to negate any residual effects from past rules you can remove the last <style> element or better yet give your <style> element an id. I'm not sure if that kind of selection would work, but it should.
var element = document.createElement('style');
element.setAttribute('type', 'text/css');
if ('textContent' in element) {
element.textContent = css;
} else {
element.styleSheet.cssText = css;
}
document.getElementsByTagName('head')[0].appendChild(element);
Can you add a style tag to the DOM, with the contents of the text-area in it? You may want to give it an id so you can change it later.
I recommend you start using a decent framework for your web/JavaScript development, personally I'd go with jQuery.
http://api.jquery.com/css/
There are some code snippets here that show you how to quickly set css properties for elements.