Head styles in emails? - css

I know to use media queries and anchor pseudo classes I need to place them in the head of an email rather than inlining the styles (impossible).
Does it make any difference with the plethora of email clients out there is the styles are written in the head like so:
<style>
body {
....
}
</style>
Or linked like so:
<link rel="stylesheet" type="text/css" href="http://example.com/mystyle.css">

Do not rely on external (<link rel="stylesheet">) or embedded style sheets (those contained within the <style> tag outside the <body> tag), these are the most important thing to avoid. **
Many email services cut everything above the body tag and disable
external style sheets.
It's best to use <style> tag inside <body>
<body>
<style type="text/css">
body {
....
}
#media only screen and (max-width: 600px) {
....
}
</style>
</body>
If you want more details you can refer to this link, It was quite helpful for me, Cheers...

Best is for style to be written in the document and not linked. Linked resources are blocked by webmail clients like Outlook.com, Yahoo and Gmail
Use this guide for style support of email clients:
https://www.campaignmonitor.com/css/

Related

How to provide a stylesheet for rendering PDFs?

Following on from a previous question, I have managed to get the 'screen' version (HTML) of a document into PDF format using the <cfdocument format="pdf"> tag. I need the styling of the PDF to be different to that of the screen version for obvious reasons (e.g. different header styles).
I know that you can use Media Queries in CSS so that different styles are applied for printing, screen, tv etc. But how do I supply a different set of CSS styles to the <cfdocument> tag so that it renders correctly?
My initial solution was to apply a class to the containing div of the <cfdocument> tag called .pdf and then write new styles for the content based on that class inside my main CSS file. So for example a style would be .pdf h1 {font-size:20px;}. The CFML would look like this:
<cfdocument type="pdf">
<link href="/css/mainStyleSheet.css" rel="stylesheet" type="text/css">
<div class="pdf">
<h1>Document Title</h1>
... {document body here} ...
</div>
</cfdocument>
Is there a better way to do this at all? Is there anyway to pass a different stylesheet just for PDF rendering? Can it be done with Media Queries perhaps?
How are you generating the PDF, via a parameter in the querystring? Something like index.cfm?page=foo&format=pdf? If you aren't, you could easily add a parameter like that, then in your CFM:
<link href="/css/mainStyleSheet.css" rel="stylesheet" type="text/css">
<cfif structKeyExists(url, "format") AND url.format EQ "pdf">
<link href="/css/pdfStyleSheet.css" rel="stylesheet" type="text/css">
</cfif>
pdfStyleSheet.css would contain only the CSS overrides for the PDF.

What is difference between external and internal css?

I watched a flex tutorial and I found parts mentionning external and internal css. So what is the differences between the two ?
External CSS refers to a file location, ie
<link rel="stylesheet" href="your-file-here.css">
Internal CSS
Means that the CSS is included on the page, wrapped in style tags in the <head>:
So:
<style>
#wrapper { width:960px; margin:0 auto; }
</style>
When internally using CSS, styles can be used in what is called inline styles.
Which looks like:
<p style="color: #333; font-size: 22px;">Blah blah blah.</p>
The only real benefit to internal CSS, is that the browser doesn't need to make an additional GET request to download the .css file. But external is preffered. As it means you just need to modify the .css file, and it will be reflected in all pages which include a reference to that specific file.
Internal CSS
Defined inside <style> elements.
Embedded directly inside the page.
External CSS
Linked via the <link rel="stylesheet"> element.
Exists as a seperate file on the server.
The main advantage of an external CSS file, is that it can be cached independently from pages, meaning that the client only needs to download it once, which saves on loading times and bandwidth.
Also, by linking many pages to once CSS file, you only need to change one place, and have all of the site immediately affected (without having to go on every page and make the change).
An internal style sheet is a style tag in the head section of the page:
<style type="text/css">
body { margin: 0; padding; 10px; }
</style>
An external style sheet is a CSS file that is used by the page from a link tag in the head section:
<link rel="stylesheet" href="pagestyles.css" />
An external style sheet can also be specificed using the #import CSS rule, either from an internal style sheet or another external style sheet:
#import "otherstyles.css";
There is also a third type of css; inline styles that are specified on the element that they apply to:
<div style="background:#ccc;">

Printing Html Document formatted with CSS

I have a asp.net mvc application and my Views are in HTML5. I need to print a view as a report. This View shows some data with <table/> tag and it is formatted with css style as font-family, font-size, text-align properties etc. When I try to print it with Chrome (exporting to PDF) my css does not work, I mean, the print's result is shown without formating.
What can I do to solve this problem? It Does not matter whether I use css to apply the style or use html tags to format the page, but I wish it would leave the impression formatted.
PS: I would like to keep the html valid document.
You need to split up the css for screen and print separately just by following setting
<link href="css/main.css" media="screen" rel="stylesheet" type="text/css" />
<link href="css/print.css" media="print" rel="stylesheet" type="text/css" />
then no need to change your html code just change the css or duplicate the old css.
You can use different styles for screen and print media in your style sheet, i.e.
#media screen
{
table.test {
font-family:"Times New Roman",Georgia;
font-size:10px;
// more
}
}
#media print
{
table.test {
font-family:Verdana, Arial;
font-size:10px;
// more
}
}
When you'll print the table only styles defined in print media will be applied.
Check this for more.
You can try to define the css semantics with #media print rule, then stylize the stylesheet with that in mind. Maybe this help.

ASP.NET MVC Inline Styling convert

Is there anyway I can get the all style of a page (even the style in some linked css files) as inline style?
For example, I have my css file:
body {
background-color: red;
color: black;
}
And this HTML:
<html>
<head>
<link href="styles.css" rel="stylesheet" type="text/css" />
</head>
<body>Hello World!</body>
</html>
So I'd like to get:
<html>
<head></head>
<body style="background-color: red; color: black;">Hello World!</body>
</html>
It would also work for me if I can get all the style in a style node.
from your comments, what you need is very different
What you are looking for is a tool that grabs an HTML page with it's own CSS styling and convert them into inline styling.
For that, plenty of tools are at your service:
http://premailer.dialect.ca/
There are more in Google, this is commonly used in Mailing as Email Client Applications do not intrepertate linked CSS but inline css.
If you are looking for a .NET solution, you might be interested in PreMailer.NET.
https://github.com/milkshakesoftware/PreMailer.Net
PreMailer pm = new PreMailer();
string premailedOutput = pm.MoveCssInline(htmlSource, false);
Old post, but I finally (2 years late!) got this up on github and in nuget:
https://github.com/lukeschafer/HtmlCleanser
Note: Premailer.Net (suggested by Arical) does not inline correctly.

Eliminate flash of unstyled content

How do I stop the flash of unstyled content (FOUC) on a web page?
The problem with using a css style to initially hide some page elements, and then using javascript to change the style back to visible after page load, is that people who don't have javascript enabled will never get to see those elements. So it's a solution which does not degrade gracefully.
A better way therefore, is to use javascript to both initially hide as well as redisplay those elements after page load. Using jQuery, we might be tempted to do something like this:
$(document).ready(function() {
$('body').hide();
$(window).on('load', function() {
$('body').show();
});
});
However, if your page is very big with a lot of elements, then this code won't be applied soon enough (the document body won't be ready soon enough) and you might still see a FOUC. However, there is one element that we CAN hide as soon as script is encountered in the head, even before the document is ready: the HTML tag. So we could do something like this:
<html>
<head>
<!-- Other stuff like title and meta tags go here -->
<style type="text/css">
.hidden {display:none;}
</style>
<script type="text/javascript" src="/scripts/jquery.js"></script>
<script type="text/javascript">
$('html').addClass('hidden');
$(document).ready(function() { // EDIT: From Adam Zerner's comment below: Rather use load: $(window).on('load', function () {...});
$('html').show(); // EDIT: Can also use $('html').removeClass('hidden');
});
</script>
</head>
<body>
<!-- Body Content -->
</body>
</html>
Note that the jQuery addClass() method is called *outside* of the .ready() (or better, .on('load')) method.
This is the one that has worked for me and does not require javascript and it works great for pages with many elements and lots of css:
First, add a dedicated <STYLE> setting for the <HTML> tag with visibility 'hidden' and opacity as '0' at the top of your HTML, e.g, in the beginning of the <HEAD> element, for example, at the top of your HTML add:
<!doctype html>
<html>
<head>
<style>html{visibility: hidden;opacity:0;}</style>
Then, at the end of your last .css stylesheet file, set the visibility and opacity styles to 'visible' and '1', respectively:
html {
visibility: visible;
opacity: 1;
}
If you already have an existing style block for the 'html' tag, then move the entire 'html' style to the end of the last .css file and add the 'visibility' and 'opacity' tags as described above.
https://gist.github.com/electrotype/7960ddcc44bc4aea07a35603d1c41cb0
A CSS-only solution:
<html>
<head>
<style>
html {
display: none;
}
</style>
...
</head>
<body>
...
<link rel="stylesheet" href="app.css"> <!-- should set html { display: block; } -->
</body>
</html>
As the browser parses through the HTML file:
The first thing it will do is hide <html>.
The last thing it will do is load the styles, and then display all the content with styling applied.
The advantage to this over a solution that uses JavaScript is that it will work for users even if they have JavaScript disabled.
Note: you are allowed to put <link> inside of <body>. I do see it as a downside though, because it violates common practice. It would be nice if there was a defer attribute for <link> like there is for <script>, because that would allow us to put it in the <head> and still accomplish our goal.
A solution which doesn't depend on jQuery, which will work on all current browsers and do nothing on old browsers, include the following in your head tag:
<head>
...
<style type="text/css">
.fouc-fix { display:none; }
</style>
<script type="text/javascript">
try {
var elm=document.getElementsByTagName("html")[0];
var old=elm.class || "";
elm.class=old+" fouc-fix";
document.addEventListener("DOMContentLoaded",function(event) {
elm.class=old;
});
}
catch(thr) {
}
</script>
</head>
Thanks to #justastudent, I tried just setting elm.style.display="none"; and it appears to work as desired, at least in current Firefox Quantum. So here is a more compact solution, being, so far, the simplest thing I've found that works.
<script type="text/javascript">
var elm=document.getElementsByTagName("html")[0];
elm.style.display="none";
document.addEventListener("DOMContentLoaded",function(event) { elm.style.display="block"; });
</script>
An other quick fix which also works in Firefox Quantum is an empty <script> tag in the <head>. This however, penalizes your pagespeed insights and overall load time.
I had 100% success with it. I think it's also the main reason, why above solutions with other JS in the works.
<script type="text/javascript">
</script>
None of the CSS-only solutions presented here work with modern browsers (asynchronous loading of css and fonts). You have to use Javascript. What I've done to avoid FOUC is:
<html>
<body onload="document.body.style.visibility=`visible`;">
<script>document.body.style.visibility=`hidden`;</script>
With this approach the body of my web page is kept hidden until the full page and CSS files are loaded. Once everything is loaded, the onload event turns the body visible. So, the web browser remains empty until a point when everything pops up on the screen.
It is a simple solution but so far it is working.
This will not affect users who have disabled Javascript because the <script> tag is ignored.
No one has talked about CSS #import
That was the problem for me i was loading two extra style sheets directly in my css file with #import
Simple solution: Replace all #import links with <link />
Every answer on this page slows down the load and it only hides the underlying issue. If you're experiencing FOUC, find out WHY it's happening and fix that.
At the core, this is happening:
because your stylesheets are not being loaded correctly: they should be loaded via link tag in the HTML, not via JavaScript
because you placed script tags before link tags, which may force a "layout operation" and trick the browser into rendering before it even attempts to load the style.
For reference, here's an example of FOUC:
I came up with a way that requires no real code change whatsoever, woohoo! My issue was related to importing several css files AFTER some javascript files.
To resolve the issue I just moved my CSS links so that they would be above my javascript imports. This allowed all my CSS to be imported and ready to go ASAP, so that when the HTML appears on the screen, even if the JS isn't ready, the page will be properly formatted
Here is my code .. hope it solve your problem
set <body style="opacity:0;">
<script>
$(document).ready(function() {
$("body").css('opacity', 1);
});
</script>
A simple solution to avoid a flash of unstyled content without javascript:
<!DOCTYPE html>
<html>
<head>
<title>Bla bla</title>
<link href="..." rel="stylesheet" />
<link href="..." rel="stylesheet" />
</head>
<body style="opacity: 0">
<!-- All HTML content here -->
<script src="..."></script>
<script src="..."></script>
<style>
body {
opacity: 1 !important;
}
</style>
</body>
</html>
When the parser arrives at the body, it is faded out using "opacity: 0". When the parser finally arrives at the very bottom after everything else is parsed, the body is faded in again using an in-page style. The !important keyword there is important ;-), because it overrules the previous inline style of the body tag.
In this case, using "opacity: 0" to fade out is better than "display: none", because if you have layout operations done by javascript, they may not work when the affected element is not rendered.
That worked for me.
The best solution I found till now is like this:
Add all styles of your header to a <style/> tag in <head/>
at the top of style tag add .not-visible-first{visibility: hidden} + other header style
Add css via JS at the end of body
document.getElementsByTagName("head")[0].insertAdjacentHTML("beforeend","<link rel=\"stylesheet\" href=\"/css/main.min.css?v=1.2.4338\" />");
And remember to add .not-visible-first{visibility: visible} to the end of main.min.css
This option will create better user experience
You could try this with vanilla
function js_method(){
//todos
var elementDiv = document.getElementById("main");
elementDiv.style.display ="block";
}
<body onload="js_method()" id="main" style="display:none">
//todos
<h2>Hello</h2>
</body>

Resources