I'm declaring custom font inside css file, using #import and assigning them to elements:
I do not have access to the head tag of the site, I'm doing it in the body...
this does not work.., My question does custom font must be declared in the head of the page in order to load?
Using jvascript
(function loadCss(url) {
var link = document.createElement("link"),
url = "App/components/core-jasmine/jasmine.css";
link.type = "text/css";
link.rel = "stylesheet";
link.href = url;
document.getElementsByTagName("head")[0].appendChild(link);
})();
Do not use #import for css files if possible (except in certain circumstances like using #media for different devices) as it can stop CSS files from loading correctly.
You can declare a link tag to import CSS outside the head tag but it can cause several issues - mainly according to W3C specs you should only declare link tags in the head tag (I.E. it would fail the W3C validator). Loading it in the document body also increases load time as the browser has to restyle the page after load.
But in theory, yes, it can be done.
Related
I am trying to style elements of SVG using CSS. I used iframe in my index.js file to reference my SVG, and the SVG displays fine. However, my CSS styling didn't apply as it would have had I just copy/pasted the SVG contents into my index.js. The contents are stored under an object #document. How do you reference iframe contents using CSS?
Are you using an <iframe> or an <object>? Your title says the former, but your questions suggests the latter.
Assuming you really mean an <iframe>. Then the answer is: you can't. CSS does not work over document boundaries. So you can't style the contents of an iframe from the page that contains the iframe. The content of the iframe is a separate file (the SVG file).
If you want to style the SVG, then you will need to put the CSS in the SVG (using a <style> element), or reference the CSS file using the XML way of including style sheets:
<?xml-stylesheet href="common.css"?>
See: https://www.w3.org/TR/xml-stylesheet/
Assuming your svg is on the same domain, you could append a stylesheet after loading via js:
let svgIframe = document.querySelector('.svgIframe');
if(svgIframe){
svgIframe.addEventListener("load",function(e){
let svgDoc = svgIframe.contentDocument;
let iframeSvg = svgDoc.querySelector('svg');
let css = document.createElementNS("http://www.w3.org/2000/svg", "style");
css.textContent = 'path{fill:red;}';
iframeSvg.appendChild(css);
});
}
So I was running my site through Google's PageSpeed Insights and it told me that I could improve CSS delivery by delaying loading non-critical resources. In particular it referenced to the inclusion of font awesome:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
I figured I could delay its load by simply putting it before the scripts before the closing body tag, like so:
...
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="js/min/scripts.min.js"></script>
</body>
</html>
However! When taking a look at Google's documentation on delivery speed, I found two different solutions.
In my native language (Dutch; you can change the language of the documtnation in the right lower corner) the documentation states that I should place non-essential css below the closing html tag. This seems awefully odd to me. Wouldn't this complicate things when trying to access the file through JS? Why wouldn't you place it before the closing body tag?
...
</body>
</html>
<link rel="stylesheet" href="small.css">
However, in the English documentation things get more complicated and require JavaScript:
...
<script>
var cb = function() {
var l = document.createElement('link'); l.rel = 'stylesheet';
l.href = 'small.css';
var h = document.getElementsByTagName('head')[0]; h.parentNode.insertBefore(l, h);
};
var raf = requestAnimationFrame || mozRequestAnimationFrame ||
webkitRequestAnimationFrame || msRequestAnimationFrame;
if (raf) raf(cb);
else window.addEventListener('load', cb);
</script>
</body>
</html>
Why would JS required? Isn't that a bit over the top?
What is wrong with my approach? Why can't you load non-critical CSS before the closing body tag?
An external stylesheet will block rendering of the page until it has been fully loaded. Google is recommending to place the style that is needed for the initially visible (critical, above the fold) part of the document inside <style> tags in the head (the only place where you can define non-inline style) to avoid this render-blocking. The non-critical style (what you don't directly see when you land on the page) is added as an external stylesheet inside the head after the HTML has been read. This way it's rendered first and only then will all other styles be loaded. All for the sake of showing the visitor the content as quickly as possible and not letting her/him wait any longer than necessary.
It think for most cases it is over the top what Google is recommending and they're just being freaky about a few milliseconds - their approach only makes sense somewhat if the CSS is huge. But I think it's hard, if not near impossible, to maintain with the current tools available. What for example if it is a returning visitor that has scrolled down the page at an earlier point and will automatically land there again (Opera is a browser that is very stubborn with this)? For that alone you'd need more JS and possibly juggle with the styles. That can't be a good way to go. And even for the initial display you'd have to stuff some media queries inside the head directly in order to try and get things right without resorting to full screen sections. That's all quite counterproductive and overcomplicating.
Putting <style> or <link> tags outside the head section might work but it's incorrect. I'm sure Google's not on that standpoint anymore and that the English version is the only valid documentation.
Edit - see comments for a nuance on this.
Even if one does do it the google way and get a 'good' score on PageSpeed Insights that doesn't mean too much. You could still hide the whole page and only show it when everything has been loaded (which isn't unusual) without that effecting the score.
I've personally decided to ignore it until they've implemented a feature where you can load CSS asynchronously (like you can with JavaScript and async already) like is announced in the documentation. It would still require a special use case then but at least you could build a framework for it. Not a fan of plugins for something rather trivial myself.
One important thing is missing in the Google documentation - providing a fallback when JavaScript has been disabled. Luckily with HTML5, <noscript> tags can be used for this :
<head>
/* other stuff */
<noscript><link rel="stylesheet" href="small.css"></noscript>
</head>
Sidenote - Google's own analytics script will prevent a perfect PageSpeed score because of the (logically) quick cache expiration they've set on it. Figure that.
I'd suggest you have a look at this repository: https://github.com/filamentgroup/loadCSS
LoadCSS is a very savvy script by the people at Filament Group to lazyload stylesheets in a way, that most browsers play along nicely.
If Javascript is disabled or for whatever reason the script won't work, there are fallbacks included as well.
To answer your specific questions:
Javascript is NOT required to accomplish what you want. There are several methods for loading CSS in a non-blocking fashion. Some rely on JS, some do not. Filamant Group's LoadCSS is a JS option. Critical Path's CSS Generator is one non-JS method. The process of generating the critical CSS can also be automated using Gulp or Grunt.
While your method will work it's not recommended. Google recommends loading the non-critical CSS files using Javascript so the CSS is loaded into the head after the page has finished loading.
Alternatives
There are 2 ways to improve your current implementation.
It sounds like you're currently loading 2 CSS files - your site's CSS, and font-awesome.min.css. This requires 2 HTTP requests and will cause a small delay. Combine the CSS from the 2 files into a single CSS file.
As the others have pointed out Google recommends inlining the critical CSS into the head of the page, and loading the remaining CSS in a non-blocking way. An alternative option I've found useful is to load the entire contents of the CSS into the head of the site within a style tag. I recommend this only if your CSS file is relatively small and minimized.
<head>
<style>
// ALL YOUR CSS
</style>
</head>
I think you are focusing on the wrong part of their (confusing) documentation. I think what they really are trying to share, is that you should put your critical CSS inlined into your html. Look at the blue class in the style tag
<html>
<head>
<style>
<!-- This is what they are trying to show -->
.blue{color:blue;}
</style>
</head>
<body>
<div class="blue">
Hello, world!
</div>
<script>
var cb = function() {
var l = document.createElement('link'); l.rel = 'stylesheet';
l.href = 'small.css';
var h = document.getElementsByTagName('head')[0]; h.parentNode.insertBefore(l, h);
};
var raf = requestAnimationFrame || mozRequestAnimationFrame ||
webkitRequestAnimationFrame || msRequestAnimationFrame;
if (raf) raf(cb);
else window.addEventListener('load', cb);
</script>
</body>
</html>
I read the same documentation in french, which seems to be as outdated as your dutch version and here again, they placed the blue class inlined
<html>
<head>
<style>
.blue{color:blue;}
</style>
</head>
<body>
<div class="blue">
Hello, world!
</div>
</body>
</html>
<link rel="stylesheet" href="small.css">
What they are trying to tell, is that critical CSS can be put directly in html without loading the whole CSS file. In their example, the blue class is critical since it is the only one used.
Concerning the outside of the html tag, It is indeed invalid HTML, but browsers seems to allow it anyway. For the JS code part I guess they are trying to add the stylesheet in the header, but only when the JS will be executed, which mean at the end of the page load. At this point, you might want to think about code readability over performance.
Well, there are 3 main sections, where You can place
first is body, second is head and third is everywhere in html, try to work with it
I am very very new to this, so I apologize if this is very simple or has been asked elsewhere.
I am using Responsive Table Generator to generate a table from a Google document that I then try to place on a webpage using their iFrame code.
The generator gives me a handful of .js files and a .html and .css file to upload to my site. I then use the provided iFrame code to embed it on the page I want.
<div id="table-iframe-container"></div>
<script src="http://nesemc.com/test/markdown-3/news-table/pym.js"></script>
<script type="text/javascript">
(function() {
var pymParent = new pym.Parent(
'table-iframe-container',
'http://nesemc.com/test/markdown-3/news-table/index.html', {});
}());
</script>
However, I believe the parent page is some how overriding the .css style of the generated table.
You can see an example here: LINK
How can I stop this?
Your styles aren't leaking. Your iframe isn't wide enough to see the "full view", and you have styles that are responsive and don't work when that small. Make your iframe wider and it'll look like you want. If you remove max-width: 960px; from the #affero-page styles in consolidated.css, you should see it.
To see what you are looking at, go to this page: http://nesemc.com/test/markdown-3/news-table/index.html?initialWidth=860&childId=table-iframe-container (your iframe content), and play with the browser width. You will see once you get too small, it then displays how you have it.
I know I can just put the <link> tag in the body and apparently it works, but I know it's not "valid" html and I want to avoid issues with strict browsers like firefox, which ignore every behavior a web designer expects if it's not defined in the official specification.
So is there some official way to load a stylesheet in the body area of the html?
You can add your css in the head dynamically as well like below:
jsCode:
var head = document.getElementsByTagName("head")[0],
cssLink = document.createElement("link");
cssLink.href = "path/to/filenam.css";
cssLink.id="dynamic-css";
cssLink.media="screen";
cssLink.type="text/css";
head.appendChild(cssLink);
document.head.appendChild( linkElement );
…where linkElement is your style link. Nobody's forcing you to add stuff to the body, just add it to the head.
It is valid to link to a stylesheet in the body
The stylesheet keyword may be used with link elements. This keyword creates an external resource link that contributes to the styling processing model. This keyword is body-ok.
https://html.spec.whatwg.org/multipage/semantics.html#body-ok
https://html.spec.whatwg.org/multipage/links.html#link-type-stylesheet
Actually in older versions of HTML it was illegal to put a link element in the body element and must be only in the head section of the HTML document. From this link, there is a section that states this
it may only appear in the HEAD section of a document
So, just simply load the stylesheet into the head element, there is no possible reason for you, or for anyone to write illegal documents that do not satisfy the rules of W3.org.
<head>
<link rel="stylesheet" href="~/css/file.css" />
</head>
However, there is another question that you might be interested in reading, and in which condition you can add link element to the body section. Read the answer here.
In Visual Studio 2010, is there a way of changing the Cascading Style sheet on the server-side based on the client browser? I want to create different style sheets for the different browsers (Firefox, Chrome, IE, Opera, Safari etc..) and specify which one to use from the master page.
I agree with KP; use a single stylesheet.
If you are using modernizr [sic], then you can style for different browsers very simply, for example:
someContainer {
/* standards based CSS */
}
someContainer.ie6 {
/* special CSS for IE6 */
}
My suggestion is to use the new HTML5 Boilerplate which includes modernizr. You'll be glad you did!
Check out the links below and don't look back. :)
Link to Boilerplate for HTML5
Link to Modernizr - ease the chaos!
Cheers
Here's a good article on detecting browser type in asp.net:
http://msdn.microsoft.com/en-us/library/3yekbd5b.aspx
Once you detect the browser type using for example, a switch statement on HttpContext.Current.Request.Browser.Type, you can easily insert a css reference into the page, with code such as:
HtmlLink cssLink = new HtmlLink();
cssLink.Attributes["type"] = "text/css";
cssLink.Attributes["rel"] = "stylesheet";
switch(HttpContext.Current.Request.Browser.Type)
{
Case "Firefox":
//use a certain path depending on browser type
cssLink.Attributes["href"] = "firefox.css";
break;
Case "Internet Explorer"
cssLink.Attributes["href"] = "IE.css";
break;
//and so on
}
Page.Header.Controls.Add(cssLink);
I don't know what the actual string values of Browser.Type will be for each browser. You'd have to test.
Even with the above, I'd still recommend using a single stylesheet for all browsers. With a little effort you can make a page render almost identically across all major browsers.
First I'd recommend starting with a reset CSS file such as the YUI 2 Reset or YUI 3 Reset. From there most styles will apply well and consistently across browsers. With all default styles reset you can build out your styles with complete control.
Unsure if I follow fully but you can specify these in the App_browsers folder of your project.