Adding CSS media queries with javascript or jQuery - javascript

I'm having some issues trying to add media queries with jQuery/javascript. I have a <div class="container"> hidden on small screens with display: none. I want to use the code below to make it show up, although I don't get any errors nothing changes.
$('.container').append('<style type="text/css">#media screen and (min-width: 1012px){ .container { "display": "block"}}</style>');
Any suggestions? Thank you.

It's will work fine if you only delete double quotes form "display": "block"
$('.container').append('<style type="text/css">#media screen and (max-width: 1012px){ .container { display: block}}</style>');
but I think better if you change your selector
$('head').append('<style type="text/css">#media screen and (max-width: 1012px){ .container { display: block}}</style>');

You can use
document.querySelector('style').textContent +=
"#media screen and (min-width: 1012px){ .container { display: 'block'}}"
Get style element and add your new rules, and your html add if no exists
<style>......</style>

The answer of CMedina is quite good, but it appends to the first style element in the document. This could be problematic in two ways:
a) There might not be style element (because <link rel="stylesheet">);
b) There might be more than one style element. Appending style rules to the first one might be overwritten by later ones.
So here's my tactic:
create a new <style> element; fill with desired content; append to the body so it comes last
const styleSheet = document.createElement('style');
styleSheet.textContent = '#media print { /* ... */ }';
document.body.appendChild(styleSheet, 'beforeend');

Related

Media Queries or JavaScript to hide an element on certain screens

We have a section on the page that needs to be hidden on small phone screens, and appear on larger screens.
The easiest way to do it would be to use CSS media queries.
.section {
display: none;
}
#media (min-width: 900px) {
.section {
display: block;
}
}
However, this would keep the section in the DOM, thus potentially making it less efficient.
Alternatively, we could toggle the existence of the section using a state in our JavaScript framework (React in our case, but not important for the question).
My Question is: When is it better to use one, and when is it fine to use the other?

Toggle Display State with Button and Media Query

I'm looking for the best way to have display state that can be toggled via a button on the page, but that can also be overridden based on a media query. On large screens I want to default to a horiz layout, and provide the choice to toggle a vert layout instead. On smaller screens, I want to default to the vert layout and not allow the toggle.
My current solution relies on cascading to override styles in the stylesheet which I would like to avoid since it requires my styles to be in a specific order.
HTML:
Apply a default layout of layout--horiz. layout is also applied in order to override the specific layouts with #media queries.
<div id='layout' class='layout layout--horiz'>
<a href="#" id='btn'>Toggle</a>
<p>This</p>
<p>is</p>
<p>a</p>
<p>test</p>
</div>
CSS:
In the #media query for small screens: hide the toggle, and hardcode the vert styles to the layout style to override the layout--horiz if applied.
#btn {
display: block;
}
.layout--horiz p {
display: inline;
}
.layout--vert p {
display: block;
}
#media screen and (max-width: 600px) {
#btn {
display: none;
}
.layout p {
display: block;
}
}
JS:
Toggle the specific --horiz and --vert classes on button click.
$('#btn').click(function() {
$('#layout').toggleClass('layout--vert layout--horiz');
});
This solution works decently, but I'm wondering if there is a better way to accomplish this.
Note: Here is a codepen to play with.
Your solution isn't far from optimal barring inclusion of your JS into a frontend framework. This is probably why you're receiving comments directing you to code review. To improve your solution use only one selector for state change. This will invoke two states to your layout layout--horiz and a default state. It's easy to make this change once you switch your media query to select for large displays instead of small ones.
HTML:
<div id='layout' class='layout layout--horiz'>
<a href="#" id='btn'>Toggle</a>
<p>This</p>
<p>is</p>
<p>a</p>
<p>test</p>
</div>
CSS:
#btn {
display: none;
}
.layout p {
display: block;
}
#media screen and (min-width: 601px) {
#btn {
display: block;
}
.layout.layout--horiz p {
display: inline;
}
}
JS:
$('#btn').click(function() {
$('#layout').toggleClass('layout--horiz');
});
I think a better way of doing this could possibly be to have two separate style sheets one with horizontal layout and the other with vertical layout and then you can switch the style sheets on click function to get the preferred layout. Here is a link to something I found really quick.
https://www.developphp.com/video/JavaScript/Change-Style-Sheet-Using-Tutorial-CSS-Swap-Stylesheet

how to make mediaQuery over write values which were set dynamically in the code?

I have a div which has a basic width value, set in a css file.
In that file, i also have a media query for a new basic width, upon orientation change to portrait.
in my javaScript i have a function updating the width dynamically when document is ready.
What happens is, that when the media query is called, the updated width - is the width which was set dynamically by the js, and it's automatically overwrites the new media query css width.
In other words, once I dynamically set the width in the code - the media query will no longer take any effect.
how can i make the media query css width overwrite the current width (which was set dynamically by js?)
THANK YOU!
HTML + JS :
<html>
<head>
<script>
var defaultNumOfItem = 3;
$(document).ready(function()
{
updateWidth(4);
});
function updateWidth(currentNumOfItems) {
var basicWidthText = $('#list').css('width');
var basicWidth = parseFloat(basicWidthText .slice(0, basicWidthText .indexOf('px')));
$('#list').css('width', basicWidth * currentNumOfItems/ defaultNumOfItem);
}
$(window).bind('orientationchange, function(){
updateWidth(4);
});
</script>
</head>
<body>
<div id='list'>
</div>
</body>
</html>
CSS:
#list {
width: 900px;
}
#media only screen and (orientation: portrait){
#list {
width: 600px;
}
}
P.S the use of !important did not work for me, since if i put it in the css - the js will take no effect. and if i put it in the js - the media query takes no effect - same will happen by putting it in both the js and the css
This can probably be achieved without JavaScript, though the full intent of the code is not totally clear, so this is how to do it while maintaining the current functionality.
#media only screen and (orientation: portrait) {
#list {
max-width: 600px;
}
}
The max-width CSS property trumps width, even if width is defined inline, externally, or made !important. The same is true of the min-width property under different circumstances.
Just give it a try !important
#media only screen and (orientation: portrait){
#list {
width: 600px !important;
}
}
If I understand this correctly you want to use the media query only if orientation is portrait and the js if the orientation is landscape. In this case you can try this:
$(window).bind('orientationchange', function(event){
if(event.orientation != "portrait")
updateWidth(4);
});
this way the js will not overwrite the width that you wanted to set through the media query in portrait
Ok, found a work around that actually works!
What i do, is simply remove the "width" attribute from the #list every time the orientation changes:
$(window).bind('orientationchange, function(){
$('#list').css('width','');
updateWidth(4);
});
so that way, the external css does take before the js manipulation.

Print sections that were hidden on the screen with javascript

I have run into a small problem I have not encountered before: I use javascript (jQuery) to show different sections of information in tabs on a web-page. So what I´m doing, is hiding the tabs that are not being viewed and only showing the tab that is being viewed.
This works very well, but now I am adding a print-specific style-sheet and I want to print the information of all tabs and not just the one being viewed.
How can I undo the javascript hiding of these sections for the print style-sheet?
Edit: Some additional information:
I am using jQuery to hide all div.tabs sections and in my print style-sheet I have set:
.wrapper div.tabs sections {
display: block;
}
assuming that the higher value of .wrapper div.tabs sections compared to div.tabs sections would make the sections visible. But it doesn´t...
The best approach would be to change the JavaScript so that it modified the classes that applied to the elements and didn't modify .style.display. Then you could target elements with those classes differently with the screen and print media stylesheets.
The quick and dirty approach would be to use !important in your print media stylesheet.
All you really need is CSS. Just define some things that show when printed.
Heres and example:
#media print {
div.print_show{ dispay: block; }
span.print_show{ display: inline; }
.print_hide{ display: none; }
}
You can add an extra class to add display:block to your print.css..

How to add Page Break dyanamically to Print page?

There is one long in the content on the print page, but while we print the some content of the text cut down.
alt text http://img694.imageshack.us/img694/6766/printpage.jpg
please let me know , if there is any dynamic way to add page-break css. the content could be any thing.
You might also just want to prevent page breaks inside an element.
E.g. short tables that you don't want to get ripped apart when printing:
#media print {
table {
page-break-inside: avoid;
}
}
As Haim Evgi referenced in this article http://davidwalsh.name/css-page-breaks
In addition to what's already described in the article, I would like to point out that it's good practice to use .page-break-before: auto instead of .page-break-before: always. The "auto" will break the page only if the contents are at the end if the page, this will prevent breaking the page and leaving a lot of blank space.
The CSS
#media all {
.page-break { display: none; }
}
#media print {
.page-break { display: block; page-break-before: auto; }
}
The HTML
<div>some content</div>
<div class="page-break">more content, this content may be short or long</div>
<div class="page-break">this content may page-break if content above this <div> is at the end of the page</div>
<div class="page-break">etc,..</div>
Use the css page-break-before and page-break-after elements.

Categories