How to apply "-webkit" css rules using jquery .css - javascript

Hey fellas and ladies,
I'm having an issue applying the following css rule.
$('#bam').css({"-webkit-overflow-scrolling": "touch"})
Is applying -webkit stuff supported in jquery being a nonstandard rule? When I apply nothing happens and no error occurs.
However if I do the the same syntax and change color it works.
As a use case im trying to fix an issue with an iphone iframe overflow problem see iframe size with CSS on iOS for my current issue and Im not in a position to use inline styles or external css.
Any ideas :)?
Added jsbin example.
https://jsbin.com/vizacezeva/edit?html
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<script>
$( document ).ready(function() {
$('#bam').css({"overflow-scrolling": "touch"})
console.log('hi');
console.log($('#bam').css("overflow-scrolling"));
});
</script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div id="bam" style="width:100%; padding:0px;">
<iframe src="http://www.jsbin.com" style="width:1px; min-width:100%; max-width:100%;">
</iframe>
</div>
</body>
</html>

Instead of adding the CSS rule with jQuery you can declare a rule in your CSS file and add a class which applies the style.
/** style.css **/
.foo { -webkit-overflow-scrolling: touch; }
// app.js
$('#bam').addClass('foo');

Related

How to create a CSS scope by JavaScript to prevent the CSS effect to another part of the page?

For example:
I have a page and the code is:
<!DOCTYPE html>
<html>
<head>
<style>
.wrap a {
color: red;
}
</style>
</head>
<body>
<div class="wrap">link</div>
</body>
</html>
And I have a common JavaScript component which will load a CSS file include the code below:
.wrap .link { color: blue; }
Then the link will change from red to blue.
Use iframe can fix this but cause another problem same like display two scrollbar or the lightbox overlay just in part of the page.
I can not change the CSS but I can write a JS loader so do you have some idea to fix this?
If a selector matches then a rule will apply until overridden by a rule (which sets the same property) further down the cascade.
You can either change your selectors to stop them matching the elements you don't want them to match, or you can override all your rules in that section.
Therefore, you'll have to adapt your markup and styles. You can precede every selector with #wrapper. For example, if a rule says a{color:red}, substitute that with #wrapper a {color:red;}.
HTML5 allows scoped stylesheets, but only Firefox supports it so far. However there is a you may try a jQuery solution: https://github.com/thingsinjars/jQuery-Scoped-CSS-plugin.
Hope it helps.
This might help you.
function changeColor(){
jQuery(".link").css('color','blue');
}
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<style>
.wrap a {
color: red;
}
</style>
</head>
<body>
<div class="wrap"><a href="#" class="link" onclick='changeColor()'>link</a></div>
</body>
</html>

Define specific CSS-style only if JavaScript is enabled

My webpage contains a DIV. If Javascript is enabled, I want the DIV to be invisible (display: none;) when the page loads. If JS is disabled, I want it to be visible (display: block;).
I can do:
document.write('<div style="display:none;">...</div>');
or
document.getElementById('foo').style.display = 'none';
With the first code there won't be a DIV if JS is disabled. With the second, the DIV will be visible when the page loads and disappear when the JS is executed.
I'm too stupid to solve this.
Can I put JavaScript inside the <div>-tag to write only the style? Certainly not like this:
<div <script>document.write('style="display:none;"');</script>>
Maybe something like:
<div onLoad="document.write('<div style="display:none;">...</div>');">
Does someone have an idea?
One problem with displaying an element unless JS hides it is that, even with JS on, the element is likely to display until the JS kicks in. So it's often better to have some JS at the top of the file that adds a class to the root element straight away, to get in before the CSS loads. Here's a simple example (in my noob JS):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script>
(function() {
var root = document.querySelector('html');
root.className = "js";
}());
</script>
<style media="all">
div {width: 500px; height: 200px; background: blue;}
.js div {display: none;}
</style>
</head>
<body>
<div></div>
</body>
</html>
This is much better than using oldfashioned <noscript> and document.write() etc.
EDIT: I should just note that an easier way to target the html element is with document.documentElement. Thus, the code above could be written as—
<script>
(function() {
document.documentElement.className = "js";
}());
</script>
Why don't you just put the <div> in a <noscript>?
<noscript><div style="display:none;">...</div></noscript>
Now you don't even have to use Javascript to deal with it.

CSS :after fails in IE8, but only after adding a reference to jQuery

It's taken me a few hours to track this issue down and I'm a bit shocked by what I am seeing.
Here's the code:
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<style>
a:after {
content: attr(data-content);
}
</style>
</head>
<body>
<a id="targetElement" href="http://www.google.com">Hello World</a>
</body>
<script type="text/javascript">
document.getElementById("targetElement").setAttribute("data-content", "moo");
</script>
</html>
The above example works appropriately in IE8. When viewed, the word 'moo' is appended to the end of targetElement:
Now, lets spice things up a little bit by reference jQuery via the CDN. Add the following line of code:
<script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery/jquery-1.8.3.min.js"></script>
such that the entire example reads as:
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<style>
a:after {
content: attr(data-content);
}
</style>
</head>
<body>
<a id="targetElement" href="http://www.google.com">Hello World</a>
</body>
<script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery/jquery-1.8.3.min.js"></script>
<script type="text/javascript">
document.getElementById("targetElement").setAttribute("data-content", "moo");
</script>
</html>
refresh IE8 and observe that the word moo has been dropped, but the element retains its data-content attribute:
I... I don't understand. I thought jQuery was supposed to be helping me out with cross-browser compatibility... but here it is wrecking shop.
Any ideas on how I can trouble shoot this? Or work around?
Alright! I spoke with Joseph Marikle in chat and we worked through a large amount of examples attempting to track down the issue.
I have good news and I have bad news. The bad news first -- I don't know exactly what the hell is going on. The good news? I've got work arounds!
So, first off, if your element is on the page at design-time (not dynamically generated) then, as long as the element's attribute exists, the css should work.
E.g.:
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<style>
a:after {
content: attr(title);
}
</style>
</head>
<body>
<a id="targetElement" title="hi" href="http://www.google.com">Hello World</a>
<script type="text/javascript">
document.getElementById("targetElement").setAttribute("title", " moo");
</script>
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.2.1.js"></script>
</body>
</html>
This example works because targetElement has the title attribute defined. The title is set to moo at run time and the css reflects this by showing content as 'moo.'
If you remove the code title="hi", you will not see moo. FURTHERMORE, if targetElement is not on the page when the css is ran -- you will not see moo -- even if you generate targetElement with the title attribute existing.
If you want to dynamically generate your elements and have this css still work... I have a second workaround for you and this is the one I am currently using. The issue seems to be that IE8 isn't finding the element when it applies pseudo-selectors and it doesn't re-run its logic when the element shows up.
So, if you do something like..
node.children('a').attr('data-content', '[' + usedRackUnits + '/' + rackTooltipInfo.rackModel.rows + ']');
var addRule = function (sheet, selector, styles) {
if (sheet.insertRule) return sheet.insertRule(selector + " {" + styles + "}", sheet.cssRules.length);
if (sheet.addRule) return sheet.addRule(selector, styles);
};
addRule(document.styleSheets[0], 'li[rel="rack"] > a:after', "content: attr(data-content)");
This will modify your stylesheet at runtime and add a new CSS rule. This causes IE8 to re-apply the logic and, because the dynamic elements are on the page now, it finds them and applies the css appropriately. Woohoo! Stupid IE8.

<noscript> tag not working

I've used the <noscript> tag to hide certain elements when javascript is not enabled; however, it doesn't seem to work.
My document declaration:
<!DOCTYPE html>
At the end of my file I typed the following:
<noscript>
<style type="text/css" scoped> #status {display:none;} </style>
</noscript>
</body>
</html>
But the #status div is still present even after disabling JS. Am I missing something here?
Remove the scoped attribute of the style tag. It's making your CSS apply strictly to the <noscript> tag.
If this attribute is present, then style applies only to its parent element.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/style#Attributes
A simpler to manage solution would be to make the element hidden by default and use this :
<script>document.getElementById('status').style.display='block';</script>
(or an equivalent class based solution)
Try removing the scope of the style, like the code below.
<noscript>
<style type="text/css"> #status {display:none;} </style>
</noscript>
#dystroy's answer is the right way of doing it, because:
<style> elements can't be placed on <body> (except if they have scoped attribute)
<noscript> elements can't be placed on head.
But if you don't want a delay, you can use the following in <head>:
<style id="noScriptSheet" type="text/css">
.onlyScript{ display:none;}
</style>
<script type="text/javascript">
function kill(el){
return el.parentNode.removeChild(el);
}
kill(document.getElementById('noScriptSheet'));
</script>
And add a class to your element:
<div class="onlyScript">Hello world!</div>
Demo: http://jsfiddle.net/TQLfu/
I am adding this answer because this seems to be the most popular SO-question regarding the noscript tag.
It doesn't seem to fire at all with "Sybu JavaScript Blocker". So in case you are testing with that JavaScript blocker try using another JavaScript blocker. When I used "Toggle Javascript" the noscript tag fired without problem. I did not yet discover a way to detect that "Sybu JavaScript Blocker" is being used.
My Testing environment:
Sybu JavaScript Blocker, Version 2.93
Toggle JavaScript, Version 1.3
Chrome, Version 85.0.4183.83

Can I not use embedded <style> CSS on Android?

I'm debugging a site on an Android HTC Sense. The site uses a lot of inserted content, which comes along with it's own CSS and JS like:
// wrapper id = snippet_id
<html>
<head>
<style type="text/css">
#snippet_id div {border: 1px solid red !important;}
div {border: 1px solid blue !important;}
</style>
</head>
<body>
<div>Hello World</div>
</body>
<html>
This is inserted into an existing page, so it sort these snippets are sort of like iFrames I guess.
Question:
Problem is, that while Javascript works fine, all CSS I'm specifying using <style> tags is being ignored. Any idea why?
EDIT:
Works on:
- Android 4.0.1
Does not work on:
- Android 2.3.1
- IOS 4.1
If I add the CSS to the main.css file being requested when the page loads, all is ok. If it's inside my gadget, it's not working.
EDIT:
So from what I can see, <style> does not seem to work on classes and id. If I use regular HTML elements as selectors it works.
EDIT:
My dev-site is here. I'm using a plugin called renderJs, which encapsultes HTML snippets (along with their CSS and JS) into resuable gadgets. Gadgets content will be appended to the page body, so although a gadget can act as a standalone HTML page, it can also be part of a page.
Example code from my page (I stripped out all gadgets but one below):
index.html - include index_wrapper gadget
<!DOCTYPE html>
<html itemscope itemtype="http://schema.org/Organization" lang="en" class="render">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="../css/overrides.css">
<script data-main="../js/main.js" type="text/javascript" src="../js/libs/require/require.js"></script>
<title></title>
</head>
<body class="splash">
<div data-role="page" id="index">
<div id="index_wrapper" data-gadget="../gadgets/index_wrapper.html"></div>
</div>
</body>
</html>
The page has a gadget called index_wrapper link - code below:
<!DOCTYPE html>
<head></head>
<body>
<div id="index_social" data-gadget="../gadgets/social.html"></div>
<p class="mini t" data-i18n="gen.disclaimer"></p>
</body>
</html>
Which has another gadget called social here. This gadget includes some CSS, but on the devices in question, it is ignored (just saw, I'm missing a </div> in the index_wrapper, so trying to see if that fixed the problem, too).
The code below includes my fix:
<!DOCTYPE html>
<head>
<style type="text/css" scoped>
// will be ignroed
.el {width: 1px;}
.menu_social {text-align: center; margin: 1em 0;}
.action_menu {display: inline-block;}
.follow_us {display: inline-block; margin: 0; padding: 0 .5em 0 0;}
...
</head>
<body>
<div class="menu_social">
<div>
<span class="el ui-hidden-accessible"></span><!-- fallback for CSS not working -->
<div data-role="controlgroup" data-type="horizontal" data-theme="c" class="action_menu">
</div>
</div>
</div>
<script type="text/javascript">
//<![CDATA[
(function () {
$(document).ready(function() {
var gadget = RenderJs.getSelfGadget();
// fallback for old devices which cannot load <style> css
if (gadget.dom.find(".el").css('width') !== "1px") {
require(['text!../css/social.css'], function (t) {
var x = '<style>'+t+'</style>';
gadget.dom.append(x);
});
}
// trigger enhancement
$(this).trigger("render_enhance", {gadget: gadget.dom});
});
})();
//]]>
</script>
</body>
</html>
So aside from probably missing a closing </div> I'm still wondering why my embedded CSS is not working.
Looking at the generated HTML code (i.e., code as modified by JavaScript) of the demo page suggests that style elements are generated inside body. Although such elements are allowed by HTML5 drafts when the scoped attribute is present, support to that attribute seems to be nonexistent, and the style sheet is applied globally. It is possible however that some browsers do not apply it at all, at least when the style element is dynamically generated.
A better approach is to make all style sheets global to the document, preferably as external style sheets, and use contextual selectors to limit the rules to some elements only. And possibly using JavaScript to change classes of elements, rather than manipulating style sheets directly.
Ok. Ugly workaround:
In the inline section, set this:
<style>
.el {width: 1px;}
</style>
In the page, set hide an element el like this:
// ui-hidden-accessible is a JQM class, moving the item out of view
// since it uses pos:absolute, is needed to not break
// selects on the page (compare to JQM ui-icon)
<span class="el ui-hidden-accessible"> </span>
Then check for the width when running inline Javascript (which works) and require the inline CSS as a separate file, when the width is not at 1px
// fallback for old devices which cannot load <style> css
// gadget is my iframe-look-a-like
if (gadget.dom.find(".el").css('width') !== "1px") {
require(['text!../css/translate.css'], function (t) {
var x = '<style>'+t+'</style>';
gadget.dom.append(x);
});
}
Ugly and an extra HTTP request, but at least the CSS is working then.

Categories

Resources