Changing media specific CSS properties from Javascript - javascript

I have a CSS property (font) that I need to be able to change from Javascript (a pulldown). However, this font should only be used when printing (#media print).
So, the javascript can't just change the value of the font, because that will effect the screen view as well. Is there a way to change ONLY the print version of the font property?
Alternatively is there a way to have a CSS property be a reference to another property?
That way, in the print CSS, I could say font:printfont, and in the screen CSS font:12. And then change the value of printfont, and it would only change the font when printing.
thanks.
EDIT: The point is that I need to be able to change the font size that the document gets printed at from the pulldown, but I don't want to change the font size that the document gets displayed at.

That's an interesting dilemma you have going on there. Off the top of my head, the only thing I can think of is to add a new tag to the header where your font-size is declared with !important. For example, in your head tags:
<style type="text/css" media="print">
.printfont {
font-size: 16px !important;
}
</style>
This will ensure that the new font-size will take precedence.
The following is a very quick example of how you may accomplish this with javascript
<script type="text/javascript">
var inlineMediaStyle = null;
function changeMediaStyle ()
{
var head = document.getElementsByTagName('head')[0];
var newStyle = document.createElement('style');
newStyle.setAttribute('type', 'text/css');
newStyle.setAttribute('media', 'print');
newStyle.appendChild(document.createTextNode('.printFont { font-size: 16px !important;}'));
if (inlineMediaStyle != null)
{
head.replaceChild(newStyle, inlineMediaStyle)
}
else
{
head.appendChild(newStyle);
}
inlineMediaStyle = newStyle;
}
</script>
Just ensure that you have onchange="changeMediaStyle()" as an attribute on your dropdown. Also, as a disclaimer in my example, I am not accounting for things like memory leaks, so you will have to work out those kind of issues on your own.
As to your alternate question, as far as I am aware, there isn't any method for declaring/using what is essentially CSS variables. However, there is currently a recommendation out there for it: http://disruptive-innovations.com/zoo/cssvariables/

seems like what you want to do is myabe just change or add a class to the item with JS
<p class="inrto comicSans">this is the text to change</p>
#screen p.intro {font-family:verdana;}
#print p.comicSans {font-family:comic-sans;}

You could just use JavaScript to switch classes, and have the
#print {
.myPrintClass { font-family: serif; }
}
#screen {
.defaultClass { font-family: sans-serif; }
}

While the class-based solutions would totally work, you could also use Javascript to dynamically add a new <link> tag to the page. For instance, if you have:
stylesheet1.css:
#print * {font-family:verdana;}
stylesheet2.css:
#print * {font-family:comicSans;}
You could then use jQuery to do something like:
$(document.body).append("<link href='stylesheet2.css'/>");
(you could do it without jQuery too, but I forget that syntax and am too lazy to look it up ;-)).
However, if you're only changing small amounts, a single stylesheet + different classes is probably the better way to go; the new <link> tag solution is only worthwhile if you have a bunch of different style changes happening.

Related

Can we Create CSS Selector rule with JQuery or Javascript?

we can create style or any other tag with
var st = document.createElement("style");
and even append the same to body
body.append(st);
and it will create
<body><style></style></body>
I wanna know can we put style in style tag with javascript as well not simple rules, I know there is $("selector").css() function is there which can apply css rules to selector but i want a bit more powerful rule and I want to add in style tag i just created,
something like this:
<style>
div.bar {
text-align: center;
color: red;
}
</style>
st.innerHtml or st.innerText are not letting me set these values.
Note: This was asked me to do in Browser Console only.
You can simply use jquery .text method like
const cssCode = `div.bar {
text-align: center;
color: red;
}`
$('style-tag-selector').text(cssCode)
but in my opinion, whetever your goal is - this solution is not ok. You shouldn't mess with CSS via JavaScript.
Best approach is to have styles in separately loaded .css file and then you can toggle classes to elements with javascript.
You can add your css directly within the style tag and append them to the head of your page:
$( "head" ).append( "<style>div.bar {text-align: center; color: red}</style>" );
You can append multiple style tags with css in the head beneath each other, in this way you can override previous syles, but it is not best practice.
I prefer having your styles in separate files and to manage wether or not the files will be included in your code.
Actually there's an interface for this. For example, add a style element and add a rule to it (this will result in anything with the class should-be-red to be red.
var styleElement = document.createElement('style');
document.head.appendChild(styleElement);
var sheet = styleElement.sheet;
sheet.insertRule('.should-be-red { color: red; }', 0);
You can iterate over the rules and insert/delete rules and exciting things like that.
More info: https://developer.mozilla.org/en-US/docs/Web/API/CSSStylesheet
jsbin: https://jsbin.com/jodiro/1/edit?html,js,output

How can I tell if a CSS property was manually set by page author?

I'd like to be able to tell if specific CSS properties (width, height, margin, padding, font-size, …) were set by the page author for a DOM element. My goal is to not change elements that have had their dimensions explicitly set, but to change those that have not.
function isPropertySet(elem, "width") should return true if the page author set the width CSS property either inline (style="width: 100px;"), or via a stylesheet.
This is not straightforward because the layout engine infers these values, and it seems that however I try to access them the browser has supplied values.
For instance, I've tried getComputedStyle(elem).getPropertyValue("width"), but this returns the computed width (not surprising given the name).
The style property, e.g. elem.style.width, isn't sufficient because it doesn't include properties set in stylesheets.
Before I go to the immense pain of searching through the stylesheets, does anyone have a better way?
Thanks!
If you want to supply default style set for the elements which were not customized, than the easiest way would be to create your own stylesheet and put it at the top, before any other CSS files. This way, every element customized elsewhere will overwrite your default styles. Be careful with the cascading order: not only your styles should precede every other, but the selectors should also be general enough.
If, on the other hand, for some reason you want to know through JavaScript whether the element was customized, then it's not possible, unless you want to compare the particular style with the default one, given that default styles may vary from browser to browser. For example, in Firefox, the default style for <h1/> is:
h1 {
display: block;
font-size: 2em;
font-weight: bold;
margin: .67em 0;
}
while Chrome has a slightly different style:
h1 {
display: block;
font-size: 2em;
-webkit-margin-before: 0.67em;
-webkit-margin-after: 0.67em;
-webkit-margin-start: 0px;
-webkit-margin-end: 0px;
font-weight: bold;
}
This creates a problematic edge case. Imagine I want all <h1/> be font-weight:normal; font-size: 200%;, but there is one specific title on one specific page which I want to be exactly 2em and be displayed in bold. You'll think that the title is not customized, and override its style, while in fact, it was customized, the size and weight being set on purpose.
If you aren't worried about inherited styles and only the specific DOM element then maybe you can dynamically create the specific element&classname (so it only has CSS styles) and then examine it's width using the above methods and compare it?
The best way I have found to answer this question from JavaScript is to create a temporary element, that is not attached to the dom, and read my default values from that. I then test the default values against the values read from the element I'm testing (using jQuery or getComputedStyle) - if they compare then it's a best guess they haven't been set. Obviously this has a downside in the fact that if the element has had it's property set to the exact same value as the default you can't tell the difference.
Something like this
function hasDefaultStyle(elm, prop) {
var def = $('<'+$(elm).attr('tagName')+' />').css(prop);
return $(elm).css('prop') == def;
}
When dealing with different dimension metrics i.e. percent, cm, em and so on - these have to be dealt with in a different way—on browsers other than FireFox at least—due to the computed problem you mention.
FireFox does the right thing in my opinion and that when you request styles from an element that hasn't been placed in the dom it returns the original values i.e. like 50%.
For more information on how to solve at least the percent problem you can see my answer here:
Determine whether element has fixed or percentage width using JavaScript
It is rather ridiculous that such methods are necessary however :/

remove / reset inherited css from an element [duplicate]

This question already has answers here:
How to reset/remove CSS styles for a specific element or selector only
(17 answers)
Closed last month.
I know this question was asked before, but before marking it as a duplicate, I want to tell you that my situation is a little different from what I found on the internet.
I'm building and embedded script that people can put it on their sites. This script creates a div with a certain width/height and some information in it.
My problem is that some websites declare styles for div that are inherited by my div as well.
for example:
div{
background-color:red;
}
so if I don't set any background color to my div, it will show red even if I don't want that.
The only solutions I come along is to overwrite as many css proprieties, this way my div will show exactly as I want.
The problem with this solution is that there are too many css proprieties to overwrite and I want my script to be as light as it can be.
So my question is if you know another solution to my problem.
It can be in css/javascript /jQuery.
Thanks
"Resetting" styles for a specific element isn't possible, you'll have to overwrite all styles you don't want/need. If you do this with CSS directly or using JQuery to apply the styles (depends on what's easier for you, but I wouldn't recommend using JavaScript/JQuery for this, as it's completely unnecessary).
If your div is some kind of "widget" that can be included into other sites, you could try to wrap it into an iframe. This will "reset" the styles, because its content is another document, but maybe this affects how your widget works (or maybe breaks it completely) so this might not be possible in your case.
Only set the relevant / important CSS properties.
Example (only change the attributes which may cause your div to look completely different):
background: #FFF;
border: none;
color: #000;
display: block;
font: initial;
height: auto;
letter-spacing: normal;
line-height: normal;
margin: 0;
padding: 0;
text-transform: none;
visibility: visible;
width: auto;
word-spacing: normal;
z-index: auto;
Choose a very specific selector, such as div#donttouchme, <div id="donttouchme"></div>. Additionally, you can add `!important before every semicolon in the declaration. Your customers are deliberately trying to mess up your lay-out when this option fails.
You could try overwriting the CSS and use auto
I don't think this will work with color specifically, but I ran into an issue where i had a parent property such as
.parent {
left: 0px;
}
and then I was able to just define my child with something like
.child {
left: auto;
}
and it effectively "reset" the property.
Technically what you are looking for is the unset value in combination with the shorthand property all:
The unset CSS keyword resets a property to its inherited value if it inherits from its parent, and to its initial value if not. In other words, it behaves like the inherit keyword in the first case, and like the initial keyword in the second case. It can be applied to any CSS property, including the CSS shorthand all.
.customClass {
/* specific attribute */
color: unset;
}
.otherClass{
/* unset all attributes */
all: unset;
/* then set own attributes */
color: red;
}
You can use the initial value as well, this will default to the initial browser value.
.otherClass{
/* unset all attributes */
all: initial;
/* then set own attributes */
color: red;
}
As an alternative:
If possible it is probably good practice to encapsulate the class or id in a kind of namespace:
.namespace .customClass{
color: red;
}
<div class="namespace">
<div class="customClass"></div>
</div>
because of the specificity of the selector this will only influence your own classes
It is easier to accomplish this in "preprocessor scripting languages" like SASS with nesting capabilities:
.namespace{
.customClass{
color: red
}
}
Try this: Create a plain div without any style or content outside of the red div. Now you can use a loop over all styles of the plain div and assign then to your inner div to reset all styles.
Of course this doesn't work if someone assigns styles to all divs (i.e. without using a class. CSS would be div { ... }).
The usual solution for problems like this is to give your div a distinct class. That way, web designers of the sites can adjust the styling of your div to fit into the rest of the design.
As long as they are attributes like classes and ids you can remove them by javascript/jQuery class modifiers.
document.getElementById("MyElement").className = "";
There is no way to remove specific tag CSS other than overriding them (or using another element).
you may use this below option.
<style>
div:not(.no_common_style){
background-color:red;
}
</style>
now , if their any place where you do not want to apply default style you can use 'no_common_style' class as class.
ex:
<div class="no_common_style">
It will not display in red
</div>
From what I understand you want to use a div that inherits from no class but yours. As mentioned in the previous reply you cannot completely reset a div inheritance. However, what worked for me with that issue was to use another element - one that is not frequent and certainly not used in the current html page. A good example, is to use instead of then customize it to look just like your ideal would.
area { background-color : red; }
One simple approach would be to use the !important modifier in css, but this can be overridden in the same way from users.
Maybe a solution can be achieved with jquery by traversing the entire DOM to find your (re)defined classes and removing / forcing css styles.

How to style JavaScript created text using CSS's #font-face

I'm trying to create a page which uses java script to get data via PHP and then display it using a custom font declared in a CSS style sheet.
The entire page should use one custom font which I have declared in the main CSS file using #font-face like so:
#font-face {
font-family: 'bauhaus';
src: url('fonts/Bauhaus.woff') format('woff'),
font-weight: normal;
font-style: normal; }
My HTML file looks like this:
<html>
<head>
<script type="text/javascript" src="resources/raphael-min.js"></script>
<script type="text/javascript" src="resources/index.js"></script>
<link href="Main.css" rel="stylesheet" type="text/css">
<style type="text/css">
#canvas_container {
width: 100%;
border: 1px solid #aaa;
font-family:'bauhaus', "Times New Roman", Times, serif;
}
</style>
</head>
<body>
<div id="canvas_container">FONTTEST</div>
</body>
</html>
Within the index.js I can create text objects using Raphaeljs' syntax like so:
var txt = paper.text(150, 590, 'Test123').attr({'font-family': bauhaus, 'font-size':'70', fill:'#000'});
If I do it like that no 'Test123' text appears at all (I assume because it can't find or use the style 'bauhaus') and if I remove the font-family attribute it shows me text using the browser's default style which in my case is Arial.
The 'FONTTEST' text on the other hand is displayed correctly using the correct #font-face Font.
Now my question is how to automatically have text created by Raphaeljs (or other Javascript libraries) follow the style declared by the CSS statements? I like using custom fonts but I can't find a proper solution on how to easily use the stylized text with Javascript.
Thanks for your help!
Rather than writing out your CSS attributes in-line in your JS, why not change your CSS at the top from #canvas_container to .canvas_container , and then put the attribute "class='canvas_container' " on all of your elements which you want that font on? Should be easier to specify the class attribute than the style attribute.
An even better approach, if you want the entire page to use your font, would be to put this in your CSS (in your case, the style element):
html, body { font-family: 'bauhaus', "Times New Roman", Times, serif; }
That will make all HTML and BODY elements use your font unless later overwritten.
Well, after a bit of searching through Raphael's code I found it automatically sets its own font style (Arial) on all its text elements. I don't think that really makes sense, especially since I couldn't figure out on how to override it with a CSS '#font-face' font, but ok.
My solution was to simply delete the automatic setting of the font attribute in Raphael's source code.
For anyone interested, it's in the part where theText is declared. Just delete the font: availableAttrs.font bit in res.attrsand everything will obey the CSS style you want.
You need to register the font with cufon. See http://raphaeljs.com/reference.html#Raphael.registerFont and https://github.com/sorccu/cufon/wiki/about.
You can assign the style of your text explicitly not thinking about what really does.
Write a specific styler object function like:
function Styler( style )
{
this._style = style;
this.get = function( text)
{
return "<span style=" + this._style + "'>" + text + "</span>";
}
}
and then use everywhere:
myStyler = new Styler( 'font-size: 20px; font-weight: bold' );
...
text1 = myStyler.get( "text1" );
text2 = myStyler.get( "text2" );

Is there any solution to disable Javascript style changes in print?

Is there any solution to disable Javascript style changes in print?
For instance, if I'm hiding something through Javascript but I want to include that hidden info in print.
I hid a div using Javascript and I want to show that div if Javascript is disabled. Now the problem is, because div is hidden using Javascript it's also not showing when the page is printed.
Use a print stylesheet, along with !important statements to force the element to be visible for printing.
<link rel="stylesheet" href="print.css" type="text/css" media="print" />
CSS:
#myDiv { display: block!important; }
I've found a workaround (at least, it works for me). In my instance i had a basic html page with some styling (screen.css & print.css) plus some javascript to progressively enhance the page with extra features, etc.
When it came time to print the page i realised that the js was affecting the layout (since i was doing some css styling via jquery).
What i ended up doing was this:
in "screen.css"
body {
background-color: #ccc; /* or whatever colour your designer chose; if it NEEDS to be white, simply change something else (e.g. background-image, font-size, etc.) */
}
in "print.css"
body {
background-color: #fff;
}
in "the-javascript-file.js"
$(document).ready(function()
{
if (isPrinting() == false)
{
init();
}
});
function isPrinting()
{
var isPrint = false;
/* I'm not 100% sure about the string literal check 'rgb(255, 255, 255)',
should do some testing here with other values || other attributes...
(font-size, color, line-height, other attributes that will have the
greatest difference / variation between "screen" and "print" styles)
*/
if ($('body').css('background-color') == 'rgb(255, 255, 255)')
{
isPrint = true;
}
return isPrint;
}
function init()
{
// All sorts of awesome goes here
}
And that was it! It worked!
Here's an overview of what's happening:
User loads page
Browser loads "screen.css"
Body background colour is set to "#ccc"
Browser loads "the-javascript-file.js"
JS checks background colour... it's "#ccc"...
JS does its thing
User hits print command
Browser loads "print.css"
Body background colour changes to "#fff"
Browser loads "the-javascript-file.js"
JS checks body background colour
JS realises background colour is "#fff"
JS does nothing :)
Hope this helps someone out there :)
The use of !important has already been mentioned, but it is a blunt instrument and things get very complicated once you start needing to override things which are already !important.
One of the great benefits of CSS is that it allows you to separate style from structure. Instead of using JS to manipulate the style of an element, use it to manipulate the structure. For example, by manipulating the className property.
Your screen media stylesheet can then hide the element, while leaving it visible for the print media stylesheet.
This has the additional benefit that you don't need to think about having to override these styles as they won't apply in the first place (for print).

Categories