I am working on an already existing webpage and want to resize some elements using CSS media queries like width but i only have access to the script file, is there a way to do this without injecting CSS in my js file?
As of now i've tried injecting my css file line by line in my js file
Although less than ideal, it seems that this is possible by creating a MediaQueryList object from window.matchMedia(), and set inline styles by listening to events for changes on it.
Detailed guide on: MDN
Here is a quick example targeting #media (max-width: 640px):
(Open full page and try change window size to see effects)
const body = document.querySelector("body");
const title = document.querySelector("h1");
const media = window.matchMedia("(max-width: 640px)");
body.style.background = media.matches ? "pink" : "lightgreen";
title.innerText = "Open full page and try change window size";
media.addEventListener("change", (event) => {
if (event.matches) {
body.style.background = "pink";
title.innerText = `Matching: ${media.media}`;
}
if (!event.matches) {
body.style.background = "lightgreen";
title.innerText = `Not matching: ${media.media}`;
}
});
<h1></h1>
The best way would be to load a stylesheet that is hosted someplace you control, and then ask JavaScript to load it in the page that you want.
Code would look like:
function loadStylesheet( absPath ) {
const linkElement = document.createElement('link');
linkElement.rel = 'stylesheet';
linkElement.href = absPath;
linkElement.type = "text/css";
const head = document.head || document.querySelector('head');
head.insertAdjacentElement('beforeend', linkElement);
}
Then you would call loadStylesheet() with your stylesheet's URL as the parameter.
I am setting up a timeline using examples from http://visjs.org/docs/timeline/#Example. Can someone tell me what I need to add a local link to the graphic I have?
I have tried a.href, but maybe I am doing something wrong. Here is a snippet with my code commented out:
var item5 = document.createElement('div');
item5.appendChild(document.createTextNode('item 5'));
item5.appendChild(document.createElement('br'));
var img5 = document.createElement('img');
// img5.a.href = 'attachments/AddDuties.pdf';
img5.src = 'icons/pdf1.png';
img5.style.width = '48px';
img5.style.height = '48px';
item5.appendChild(img5);
Here is the some more code (I cut parts out to reduce size, it works before I add my own code below on image 5:). Image 5 is the one I want link the graphic to a file.
<title>Timeline | Basic demo</title>
<script src="vis-4.21.0/dist/vis.js"></script>
<link href="vis-4.21.0/dist/vis.css" rel="stylesheet" type="text/css" />
</head>
<body>'
<script>
// create a couple of HTML items in various ways
var item1 = document.createElement('div');
item1.appendChild(document.createTextNode('item 1'));
var item4 = 'item <span class="large">4</span>';
**var item5 = document.createElement('div');
item5.appendChild(document.createTextNode('item 5'));
item5.appendChild(document.createElement('br'));
var img5 = document.createElement('img');
// img5.a.href = 'attachments/AddDuties.pdf';
img5.src = 'icons/pdf1.png';
img5.style.width = '48px';
img5.style.height = '48px';
item5.appendChild(img5);**
</body>
I expect to be able to click the graphic and follow the assigned link. I know how to use href in HTML, I just dont know what code needs to tell javascript how to link the graphic in image 5.
href is an attribute for the <a> tag. you can't add href to an image.
What you should do is create an <a> element assign the href you want to it and
append the img as a child of that <a> element.
<a href="{whatever you want}">
<img src=....>
</a>
edit:
if for some reason you can't wrap the image with an <a> you could assign and id to the image and then add an event listener for a click that will redirect you.
I have to print the contents of a dialog. I'm adding a empty iframe then i add contents to it in javascript.
this is my js code where i add html and css as children of iframe
var layoutCSS = new String('<link href="css/ReportPageOne.css" rel="stylesheet" type="text/css">');
var pageOneCSS = new String('<link href="css/ReportLayout.css" rel="stylesheet" type="text/css">');
var pageTwoCSS = new String('<link href="css/ReportPageTwo.css" rel="stylesheet" type="text/css">');
var materialityCSS = new String('<link href="css/MaterialityMatrix.css" rel="stylesheet" type="text/css">');
window.frames.print_frame.document.head.innerHTML = layoutCSS + pageOneCSS + pageTwoCSS + materialityCSS;
window.frames.print_frame.document.body.innerHTML = $('#__dialog1-cont').html();
window.frames.print_frame.window.focus();
window.frames.print_frame.window.print();
opens the print dialog properly but css is not applied quite well.
On print page in options i checked in 'Background graphichs' and i am using google chrome.
You are calling frame.print() before the styles have loaded.
"The load event fires once the stylesheet and all of its imported content has been loaded and parsed, and immediately before the styles start being applied to the content."
Try this:
head.lastChild.addEventListener("load", function (event) {
// In IE, you have to focus() the Iframe prior to printing
// or else the top-level page will print instead
frame.focus();
frame.print();
}, 0);
References
https://github.com/abbotto/teleprint/blob/master/src/components/print.js
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#Stylesheet_load_events
I am doing a simple print option that when click I call a print function. The function copies over the relevant (not all of it) html.
function print() {
var printWindow = window.open("", "Print", "status=no, toolbar=no, scrollbars=yes", "false" );
var toInsert = $("div.book").html();
$(printWindow.document.body).html(toInsert);
}
The problem I have is that this new window doesn't seem to be able to reference my css stylesheet or my pictures that are within the folder. Any ideas? Just focusing on the css issue, would it be possible to insert a <link ... /> into the head of the new window?
Thanks!
function Print() {
var printWindow = window.open("", "Print", "status=no, toolbar=no, scrollbars=yes", "false" );
$("link, style, script").each(function() {
$(printWindow.document.head).append($(this).clone())
});
var toInsert = $("div.book").html();
$(printWindow.document.body).append(toInsert);
}
DEMO
It's a totally new window. It has to have its own CSS etc.
When you write a document into it, you have to write in the <link> tags, <script> tags, and everything else like that.
To dynamically insert a link to an existing CSS stylesheet into the head of the new window this worked well for me:
var cssNode = document.createElement('link');
cssNode.type = 'text/css';
cssNode.rel = 'stylesheet';
cssNode.href = 'http://www.somedomain.com/styles/FireFox.css';
cssNode.media = 'screen';
cssNode.title = 'dynamicLoadedSheet';
printWindow.document.getElementsByTagName("head")[0].appendChild(cssNode);
Source: Totally Pwn CSS with Javascript - Has some other interesting tricks around direct manipulation of a stylesheet
I'm looking for a way to insert a <style> tag into an HTML page with JavaScript.
The best way I found so far:
var divNode = document.createElement("div");
divNode.innerHTML = "<br><style>h1 { background: red; }</style>";
document.body.appendChild(divNode);
This works in Firefox, Opera and Internet Explorer but not in Google Chrome. Also it's a bit ugly with the <br> in front for IE.
Does anyone know of a way to create a <style> tag that
Is nicer
Works with Chrome?
Or maybe
This is a non-standard thing I should avoid
Three working browsers are great and who uses Chrome anyway?
Try adding the style element to the head rather than the body.
This was tested in IE (7-9), Firefox, Opera and Chrome:
var css = 'h1 { background: red; }',
head = document.head || document.getElementsByTagName('head')[0],
style = document.createElement('style');
head.appendChild(style);
style.type = 'text/css';
if (style.styleSheet){
// This is required for IE8 and below.
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
<style> tags should be placed within the <head> element, and each added tag should be added to the bottom of the <head> tag.
Using insertAdjacentHTML to inject a style tag into the document head tag:
Native DOM:
document.head.insertAdjacentHTML("beforeend", `<style>body{background:red}</style>`)
jQuery:
$('<style>').text("body{background:red}").appendTo(document.head)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
I'm assuming that you're wanting to insert a style tag versus a link tag (referencing an external CSS), so that's what the following example does:
<html>
<head>
<title>Example Page</title>
</head>
<body>
<span>
This is styled dynamically via JavaScript.
</span>
</body>
<script type="text/javascript">
var styleNode = document.createElement('style');
styleNode.type = "text/css";
// browser detection (based on prototype.js)
if(!!(window.attachEvent && !window.opera)) {
styleNode.styleSheet.cssText = 'span { color: rgb(255, 0, 0); }';
} else {
var styleText = document.createTextNode('span { color: rgb(255, 0, 0); } ');
styleNode.appendChild(styleText);
}
document.getElementsByTagName('head')[0].appendChild(styleNode);
</script>
</html>
Also, I noticed in your question that you are using innerHTML. This is actually a non-standard way of inserting data into a page. The best practice is to create a text node and append it to another element node.
With respect to your final question, you're going to hear some people say that your work should work across all of the browsers. It all depends on your audience. If no one in your audience is using Chrome, then don't sweat it; however, if you're looking to reach the biggest audience possible, then it's best to support all major A-grade browsers
Here's a script which adds IE-style createStyleSheet() and addRule() methods to browsers which don't have them:
if(typeof document.createStyleSheet === 'undefined') {
document.createStyleSheet = (function() {
function createStyleSheet(href) {
if(typeof href !== 'undefined') {
var element = document.createElement('link');
element.type = 'text/css';
element.rel = 'stylesheet';
element.href = href;
}
else {
var element = document.createElement('style');
element.type = 'text/css';
}
document.getElementsByTagName('head')[0].appendChild(element);
var sheet = document.styleSheets[document.styleSheets.length - 1];
if(typeof sheet.addRule === 'undefined')
sheet.addRule = addRule;
if(typeof sheet.removeRule === 'undefined')
sheet.removeRule = sheet.deleteRule;
return sheet;
}
function addRule(selectorText, cssText, index) {
if(typeof index === 'undefined')
index = this.cssRules.length;
this.insertRule(selectorText + ' {' + cssText + '}', index);
}
return createStyleSheet;
})();
}
You can add external files via
document.createStyleSheet('foo.css');
and dynamically create rules via
var sheet = document.createStyleSheet();
sheet.addRule('h1', 'background: red;');
An example that works and are compliant with all browsers :
var ss = document.createElement("link");
ss.type = "text/css";
ss.rel = "stylesheet";
ss.href = "style.css";
document.getElementsByTagName("head")[0].appendChild(ss);
const style = document.createElement("style")
style.textContent = "h1 { background-color: red; }"
document.head.appendChild(style)
The Modern & Easy Way
The code above is the gist of it; continue reading if you want to know the reasoning.
Why another answer? The accepted answer is old and includes redundant code for outdated browsers like the Internet Explorer. Other answers are unnecessarily complex or use properties like .innerHTML that allow for cross-site scripting attacks.
The type property is not needed
Most of the anwsers set the type property like so: style.type = "text/css". Setting this property is not necessary unless you need to support older browsers.
According to <style>: The Style Information element - HTML | MDN, the type attribute is optional and defaults to text/css:
type
This attribute defines the styling language as a MIME type (charset should not be specified). This attribute is optional and defaults to text/css if it is not specified; values other than the empty string or text/css are not used. Note: There is very little reason to include this attribute in modern web documents.
Adding the CSS
To add the CSS, use .textContent as it is safer and faster than alternative methods. Opposite to .innerHTML, it does not parse HTML and can therefore prevent cross-site scripting attacks.
Another similar property, .innerText, is like .textContent but takes CSS styles into account and represents only the "rendered" text content. As we are not interested in "rendered"-only content we prefer .textContent.
What does setting .textContent do?
Setting the .textContent property removes all the node's (element's) children and replaces them with the given string value.
Where to place the element?
The style element should be included in the head: "The <style> element must be included inside the <head> of the document. ...". [<style> ... | MDN]
To get the head use document.head as it has been supported by all major browsers for a long time already so there is no need for other fallbacks.
document.head.innerHTML += `
<style>
h1 {
color: red;
}
p {
color: blue;
}
</style>`
<h1>I'm red!</h1>
<p>I'm blue!</p>
By far the most straightforward solution. All you have to do is type the same as how you'd normally declare style tags, between the backticks
Oftentimes there's a need to override existing rules, so appending new styles to the HEAD doesn't work in every case.
I came up with this simple function that summarizes all not valid "append to the BODY" approaches and is just more convenient to use and debug (IE8+).
window.injectCSS = (function(doc){
// wrapper for all injected styles and temp el to create them
var wrap = doc.createElement('div');
var temp = doc.createElement('div');
// rules like "a {color: red}" etc.
return function (cssRules) {
// append wrapper to the body on the first call
if (!wrap.id) {
wrap.id = 'injected-css';
wrap.style.display = 'none';
doc.body.appendChild(wrap);
}
// <br> for IE: http://goo.gl/vLY4x7
temp.innerHTML = '<br><style>'+ cssRules +'</style>';
wrap.appendChild( temp.children[1] );
};
})(document);
Demo: codepen, jsfiddle
This object variable will append style tag to the head tag with type attribute and one simple transition rule inside that matches every single id/class/element. Feel free to modify content property and inject as many rules as you need. Just make sure that css rules inside content remain in one line (or 'escape' each new line, if You prefer so).
var script = {
type: 'text/css', style: document.createElement('style'),
content: "* { transition: all 220ms cubic-bezier(0.390, 0.575, 0.565, 1.000); }",
append: function() {
this.style.type = this.type;
this.style.appendChild(document.createTextNode(this.content));
document.head.appendChild(this.style);
}}; script.append();
Here is a variant for dynamically adding a class
function setClassStyle(class_name, css) {
var style_sheet = document.createElement('style');
if (style_sheet) {
style_sheet.setAttribute('type', 'text/css');
var cstr = '.' + class_name + ' {' + css + '}';
var rules = document.createTextNode(cstr);
if(style_sheet.styleSheet){// IE
style_sheet.styleSheet.cssText = rules.nodeValue;
} else {
style_sheet.appendChild(rules);
}
var head = document.getElementsByTagName('head')[0];
if (head) {
head.appendChild(style_sheet);
}
}
}
You wrote:
var divNode = document.createElement("div");
divNode.innerHTML = "<br><style>h1 { background: red; }</style>";
document.body.appendChild(divNode);
Why not this?
var styleNode = document.createElement("style");
document.head.appendChild(styleNode);
Henceforward you can append CSS rules easily to the HTML code:
styleNode.innerHTML = "h1 { background: red; }\n";
styleNode.innerHTML += "h2 { background: green; }\n";
...or directly to the DOM:
styleNode.sheet.insertRule("h1 { background: red; }");
styleNode.sheet.insertRule("h2 { background: green; }");
I expect this to work everywhere except archaic browsers.
Definitely works in Chrome in year 2019.
All good, but for styleNode.cssText to work in IE6 with node created by javascipt, you need to append the node to the document before you set the cssText;
further info # http://msdn.microsoft.com/en-us/library/ms533698%28VS.85%29.aspx
This function will inject css whenever you call the function appendStyle like this:
appendStyle('css you want to inject')
This works by injecting a style node into the head of the document. This is a similar technique to what is commonly used to lazy-load JavaScript.
It works consistently in most modern browsers.
appendStyle = function (content) {
style = document.createElement('STYLE');
style.type = 'text/css';
style.appendChild(document.createTextNode(content));
document.head.appendChild(style);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<h1>Lorem Ipsum</h1>
<p>dolar sit amet</p>
<button onclick='appendStyle("body { background-color: #ff0000;}h1 { font-family: Helvetica, sans-serif; font-variant: small-caps; letter-spacing: 3px; color: #ff0000; background-color: #000000;}p { font-family: Georgia, serif; font-size: 14px; font-style: normal; font-weight: normal; color: #000000; background-color: #ffff00;}")'>Press me to inject CSS!</button>
</body>
</html>
You can also lazy-load external CSS files by using the following snippet:
appendExternalStyle = function (content) {
link = document.createElement('LINK');
link.rel = 'stylesheet';
link.href = content;
link.type = 'text/css';
document.head.appendChild(link);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
html {
font-family: sans-serif;
font-display: swap;
}
</style>
</head>
<body>
<h1>Lorem Ipsum</h1>
<p>dolar sit amet</p>
<button onclick='appendExternalStyle("data:text/css;base64,OjotbW96LXNlbGVjdGlvbntjb2xvcjojZmZmIWltcG9ydGFudDtiYWNrZ3JvdW5kOiMwMDB9OjpzZWxlY3Rpb257Y29sb3I6I2ZmZiFpbXBvcnRhbnQ7YmFja2dyb3VuZDojMDAwfWgxe2ZvbnQtc2l6ZToyZW19Ym9keSxodG1se2NvbG9yOnJnYmEoMCwwLDAsLjc1KTtmb250LXNpemU6MTZweDtmb250LWZhbWlseTpMYXRvLEhlbHZldGljYSBOZXVlLEhlbHZldGljYSxzYW5zLXNlcmlmO2xpbmUtaGVpZ2h0OjEuNjd9YnV0dG9uLGlucHV0e292ZXJmbG93OnZpc2libGV9YnV0dG9uLHNlbGVjdHstd2Via2l0LXRyYW5zaXRpb24tZHVyYXRpb246LjFzO3RyYW5zaXRpb24tZHVyYXRpb246LjFzfQ==")'>press me to inject css!</button>
</body>
</html>
as i know there are 4 ways to do that.
var style= document.createElement("style");
(document.head || document.documentElement).appendChild(style);
var rule=':visited { color: rgb(233, 106, 106) !important;}';
//no 1
style.innerHTML = rule;
//no 2
style.appendChild(document.createTextNode(rule));
//no 3 limited with one group
style.sheet.insertRule(rule);
//no 4 limited too
document.styleSheets[0].insertRule('strong { color: red; }');
//addon
style.sheet.cssRules //list all style
stylesheet.deleteRule(0) //delete first rule
If the problem you're facing is injecting a string of CSS into a page it is easier to do this with the <link> element than the <style> element.
The following adds p { color: green; } rule to the page.
<link rel="stylesheet" type="text/css" href="data:text/css;charset=UTF-8,p%20%7B%20color%3A%20green%3B%20%7D" />
You can create this in JavaScript simply by URL encoding your string of CSS and adding it the HREF attribute. Much simpler than all the quirks of <style> elements or directly accessing stylesheets.
let linkElement: HTMLLinkElement = this.document.createElement('link');
linkElement.setAttribute('rel', 'stylesheet');
linkElement.setAttribute('type', 'text/css');
linkElement.setAttribute('href', 'data:text/css;charset=UTF-8,' + encodeURIComponent(myStringOfstyles));
This will work in IE 5.5 upwards
Anyone who is looking for Typescript version,
const addStyles = (styles) => {
let styleNode : HTMLStyleElement = document.createElement('style');
styleNode.type = 'text/css';
if (styleNode.style)
styleNode.style.cssText = styles;
else
styleNode.appendChild(document.createTextNode(styles));
/* Append style to the head element */
document.head.appendChild(styleNode);
}
Also, in react/vue/angular if direct injection of CSS is needed, you can use posstcss-js to convert CSS into JSS and use CSS-in-JSS to inject a new styleSheet directly. For more info, please follow this documentation.
Update
You can use document.head as well as per #Brandon McConnell's comment.
The most trival answer:
function addStyle (styleText) {
const styleNode = document.createElement('style');
styleNode.type = 'text/css';
styleNode.textContent = styleText;
document.documentElement.appendChild(styleNode);
return styleNode;
}
this link may helpful to you:
http://jonraasch.com/blog/javascript-style-node