jonkemp / inline-css Goto Github PK
View Code? Open in Web Editor NEWInline css into an html file.
License: MIT License
Inline css into an html file.
License: MIT License
Hello!
Thank you for this great library!
But, is it possible to exclude some CSS styles from inlining/removal? I want only a subset of styles to be inlined.
Consider this example:
<style>
p {
font-size: 12px;
}
</style>
<style data-no-inline>
a {
color: red;
}
</style>
I want first styles to be inlined, but second styles skipped and leaved as is.
Thanks!
Hey, we're a SF company and we use your library, we're pretty happy with it keep up the good work!
There's something we noticed:
When there's an interpolated variable like <p class="paragraph" style="background: {{color}]>hello</p>
, the styles from the class won't be part of the style attribute, and also this breaks the inline styles of other <p>
tags in the same template, they don't get the styles either.
When I have this in my css
a:hover {
text-decoration: underline;
}
and it gets inlined, then inline-css does not include them for links. Why?
I would appreciate adding of sortAlphabetically
option, which would be set to true
in default (to be compatible with older versions). That's because I need special CSS attributes for older IEs starting with underscore to be defined after their standard relatives, but inline-css sorts them before their standard relatives. That means the standard attribute overwrites its behaviour.
Before inlining:
div {
width: auto;
_width: 230px;
}
After inlining:
<div style="_width:230px;width:auto;">...</div>
which means that even in old IEs 230px
is overwritten by auto
.
Up inlining - your inliner is turning all of my '&" into the html element '&' So now any url's and non breaking spaces are now '&amp;nbsp;
'
I'm using gulp-inline-css in a project, but I additionally have to use gulp-attr-remover to remove the classes, because I don't need them anymore after the CSS is inlined.
Maybe this could be added to the inline-css core?
Hello, I'm install module form gulp-inliner-css - but module inline-css not actual include code(in git correct). I can't understand why?
Hello!
This code:
.class { background: -webkit-linear-gradient(-45deg, #306ab2 0%, #00e1ed 70%, #00e1ed 70%); }
Inlines like a:
<div class="class" style="background: -webkit-linear-gradient(-45deg, #306ab20%, #00e1ed70%, #00e1ed70%);">Some content</div>
We losing "spaces" between color hashes and percent values.
please bump version number and republish to NPM!
(trying to switch back from our breather fork)
Not sure if this qualifies as an issue & perhaps I am simply missing ou on something but .
the example does not work for me.
var inlineCss = require('inline-css'); var html = "<style>div{color:red;}</style><div/>"; inlineCss(html,options) .then(function(html) { console.log(html); });
will simply throw an error :
options.url is required...
providing an empty string on options.url
will result in the same thing.
my script only inline <style><style> ... no tag.
not sure what I am supposed to provide in the options.url property... :S
UPDATE :
just noticed that if you pass a random string.
the module works as expected...
just not sure what options.url actually does in that case... not seeing any files being created..
When two selectors match the same element, and both have !important
, then the selector specificity is ignored and the last rule wins:
inlineCss('<style>p a {color: red!important} a{color: black!important}</style> <p><a>test', {url: '/'}).then(s=>console.log(s))
// '<p><a style="color: black;">test</a></p>'
inlineCss('<style>a{color: black!important} p a {color: red!important}</style> <p><a>test', {url: '/'}).then(s=>console.log(s))
// '<p><a style="color: red;">test</a></p>'
However for the browsers it’s different. No matter which rule goes first, if both have !important in them, the more specific wins.
To stop underlining links in Outlook web app you have to set the following rule:
a {
text-decoration: none !important;
text-decoration: none;
}
What i get after running inline-css plugin is:
<a style=" text-decoration: none;">
I think this plugin should not be so smart and should inline my css as it is leaving both rules in same order.
It would be great if you will add such option to API or point me at module which is responsible for combining css properties.
How can we reproduce this bug?
If you include the following markup in order for my email sender to inject a dynamic coupon code into individual emails.
<<LCG Program\TG LCG Coupon Code Default='246996'>>
After the code above is run through the inliner, the result is below.
<<lcg program\tg="" lcg="" coupon="" code="" default="246996">></lcg>
What happened instead?
The code shouldn't have broken. My expectation was that it would be as I entered it.
<<LCG Program\TG LCG Coupon Code Default='246996'>>
I also reference this bug in the foundation forum here:
http://foundation.zurb.com/forum/posts/39801-question-about-characters-changing-after-using-in-liner-using-sass-version-of-foundation-for-emails
I have some html tags with multiple css classes, such as <th class="small-12 large-12 columns first last">foo</th>
. For these, the inliner fails to inline the following and similar CSS statements:
th.large-12.last { padding-right: 3px; }
No style
attribute is added by the inliner!
I use a lot of and since the Inliner change, they aren't replaced correctly. I get the following instead so I end up seeing the code for what it is in my result and see this ( &nbsp; ) in my code.
The code <title><%= @rails %></title>
is mangled into <title><%= @rails="" %=""></%>
This does not fit the XML interpretation of PIs (and is why you had to special-case doctypes, which are also PIs)
Hi! This plugin is so usefull.
I'm trying to link a external CSS to my email template. Before this step the CSS was in HEAD section and this want a problem. But i want use SASS as pre-processor to make it simpler. So i need a external CSS file. But when i try to include the CSS file, inline-css print this in console:
{ Error: getaddrinfo ENOTFOUND main.css main.css:80
at errnoException (dns.js:28:10)
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:79:26)
code: 'ENOTFOUND',
errno: 'ENOTFOUND',
syscall: 'getaddrinfo',
hostname: 'main.css',
host: 'main.css',
port: 80,
response: undefined }
This is the code:
const fs = require('fs');
const inlineCss = require('inline-css');
fs.readFile('entry.html', 'utf8', (err, data) => {
inlineCss(data, { url: './', removeHtmlSelectors: true }).then(html => {
fs.writeFile('index.html', html);
}).catch(function(reason) {
console.log(reason);
});
});
And this is the HTML:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link href="main.css" rel="stylesheet">
</head>
<body>
...
</body>
</html>
I have also tried '/', '.'.
I can't understand where is the problem. In the example i link the file in the same way.
Thanks in advance!
Was it work in browsers?
Love inline-css. it's great.
One thing that would be really helpful would be the ability to choose which which stylesheets get put in a <style> tag at the beginning of the document.
foundation-emails have been using capital M margin as well as lowercase M margin. The reason for this is that by standards it should be lower case, however Outlook web client requires it to be upper case.
I created a "technical solution" in foundation/foundation-emails#443, which they suggested I ask to incorporate it into the inliner.
If you agree, I can create a PR for do it, but i was thinking it should probably be encapsulated in a flag such as 'emailAttributes' or so, so that for normal use cases we don't inject Margin everywhere.
In order to predictably add height to an element in email developer, the height attribute is necessary. Recommend adding a applyHeight setting that works exactly as the applyWidth setting.
Hey there,
So, the following code:
var inlineCss = require('inline-css');
var html = "<style>h2{color:red;}</style><h2><%= raw_slide_data slide, :title %></h2>";
inlineCss(html, {applyStyleTags: false, url: 'https://google.com'})
.then(function(html) { console.log(html); });
Returns:
<h2><%= raw_slide_data="" slide,="" :title="" %=""></%=></h2>
I guess the equals symbol in the opening ERB delimiter (<%=) is what makes inliner add others equals and double quotes. Should we consider this as an issue? Or maybe there is a way I could work around this?
For the story, I'm working on building emails with Foundation for Emails (this tells you from how far I'm coming down the road to solving my problem) to use within a Rails project (that's why I have ERB variables in my HTML).
Stucked with an issue trying to provide relative path to url
option.
Later realized it actually requires absolute path, with the protocol
specified.
Checked the tests in repo and got the setup from there,
It only worked with the following:
inlineCss(html, {
url: 'file://' + htmlFolder + '/'
})
this is inconvenient for the config,
it's seems that the option with requiring and feeding CSS file is more attractive.
(extraCss: cssContents
)
Could you explain why it is like that
and are there ways to improve that?
The example html content:
<style>
/* somebody <[email protected]> */
.content {
background: #002b36;
color: #839496;
}
</style>
<div class="content">Hello!</div>
The error result is:
<style>
/* somebody <[email protected]> */
.content {
background: #002b36;
color: #839496;
}
</[email protected]></style>
<div class="content">Hello!</div>
The result should be:
<div class="content" style="background: #002b36; color: #839496;">Hello!</div>
If media query CSS is passed into the extraCss
option and preserveMediaQueries
is true
, or if CSS is added through a <link>
tag, the media query-specific CSS isn't preserved in the HTML output.
The use case for working with applyLinkTags
is using inline-css in a basic web development workflow, where you have separate HTML and CSS files, and some CSS is inside of media queries and needs to be preserved in the inlined HTML.
The use case for working with extraCss
is running inline-css in the browser, where we're avoiding having to read or write from a filesystem. So instead of using <link>
tag replacement, all of the CSS to be inlined is passed through extraCss
.
Ideally the media query CSS in extraCss
can be dropped into a <style>
tag in the final output. I can think of a workaround, but it would be nice if the library could handle it.
Also an FYI, version 2 of Foundation for Emails (formerly Ink) will be using this library to inline CSS :)
root@30c7a47055f5:/tmp# node gulp-inline-css-demo1.js
Error: empty style element
at Object.<anonymous> (/tmp/node_modules/style-data/index.js:30:22)
at exports.each (/tmp/node_modules/cheerio/lib/api/traversing.js:293:24)
at module.exports (/tmp/node_modules/style-data/index.js:25:16)
at /tmp/node_modules/extract-css/index.js:14:9
at next (/tmp/node_modules/batch/index.js:118:7)
at Batch.end (/tmp/node_modules/batch/index.js:154:5)
at module.exports (/tmp/node_modules/extract-css/index.js:24:11)
at /tmp/node_modules/inline-css/lib/inlineContent.js:15:9
at tryCatcher (/tmp/node_modules/bluebird/js/main/util.js:26:23)
at Promise._resolveFromResolver (/tmp/node_modules/bluebird/js/main/promise.js:483:31)
at new Promise (/tmp/node_modules/bluebird/js/main/promise.js:71:37)
at inlineContent (/tmp/node_modules/inline-css/lib/inlineContent.js:8:12)
at /tmp/node_modules/inline-css/index.js:27:9
at tryCatcher (/tmp/node_modules/bluebird/js/main/util.js:26:23)
at Promise._resolveFromResolver (/tmp/node_modules/bluebird/js/main/promise.js:483:31)
at new Promise (/tmp/node_modules/bluebird/js/main/promise.js:71:37)
gulp-inline-css-demo1.js
const fs = require('fs');
const inlineCss = require('inline-css');
var options = {
xmlMode: true
};
options.url = 'file://./test-data/from-pdf2htmlex/geneve.html';
fs.readFile('./test-data/from-pdf2htmlex/geneve.html', 'utf8', (err, data) => {
inlineCss(data, options).then(html => {
fs.writeFile('./test-data/from-pdf2htmlex/index.html', html);
}).catch(function(reason) {
console.log(reason);
});
});
geneve.html
http://coolwanglu.github.io/pdf2htmlEX/demo/geneve.html
I know thats way more complex but is it possible to also support the following:
div.info::before {
content: 'Info';
background-color: #66dd66;
}
Hi,
I'm parsing my code with inline-css and have error:
Unhandled rejection Error: Error: Unexpected }
with part of css:
@supports (-ms-accelerator:true){.trumbowyg-box-blur .trumbowyg-editor *,.trumbowyg-box-blur .trumbowyg-editor::before{color:rgba(200,200,200,.6)!important;}}
I can't remove this part even if I don't want it, because it comes with other node package (Trumbowyg wysiwyg) and it's automatically loaded and compiled into main css file from node_modules.
Is there any way to omit some selectors when passing html into inlineCss(html...)?
Thanks.
would be great to convert background colors set on the bgcolor
attribute to use best practices, (always hex with 6 chars)
Im getting <table width="600px" ...>
instead of <table width="600" ...>
using it with gulp-inline-css 3.1.0.
I use the inline-css - works very well.
I also use PreserverMediaQueries - works very well too!
Wondering if I could request an add-on to somehow preserve or not remove any embedded css or css within some "Not inline" comment. Thanks! Loving this!
At the moment when I run inline-css it seems to remove all @font-face queries from my html file. Is there some way that, like media queries, these can be ignored?
Thanks!
Hi All, firstly thanks for the library - it's saved me a great deal of time!
At the moment, the library has the option to either keep all HTML selectors or remove them; but I think there might be cases where it would be useful to have the option to set class and ID selectors individually.
In my case, I originally had this option set to (to keep the output lean) but have now had to enable it since the code base now uses in-page links (which were being broken due to the ID attribute being removed from target sections). If the library allowed id/class attributes to be preserved independanly then I'd be able to strip out just the class attributes.
<meta charset="UTF-8">
should be above any <style>
because browsers are only looking at the first N bytes to get the encoding.
This issue originally started in gulp-inline-css.
I've played around with the tests in the project and if I change media-preserve.html
to use <link rel="stylesheet" href="media-preserve.css" />
and move the CSS to that file then no CSS is included in the test output. If I try to add some media-query CSS to any other test that already uses external CSS files as part of the test, like in.html
/file.css
, and set the preserveMediaQueries: true
option, I get the same result: no media query CSS is preserved.
To double check I added some media queries CSS as <style>
in the HTML file I originally had issues with then those media queries are preserved, but the ones in my CSS file are ignored. Maybe this is by design? It's not super clear from the documentation although reading it now I can imagine it's technically correct. But since the main use case is Useful for emails
according to the readme and it already supports applyLinkTags
by default, so I assumed it would be preserved since that's the only way to make media queries work in emails.
The documentation on this option is very meager. There are two earlier issues describing misunderstanding the option. It would be great to make this easier to jump in.
Am I right to interpret that this is an absolute path that is prepended to any relative paths in the CSS? If that's true it's probably good to add that to the docs. (and if not: the actual truth ;) )
Since it's required; Adding it to the examples instead of an options
placeholder is probably also a good idea. That makes the example ready to go.
Cheers!
Can i use this with webpack? May be who solved this problem?
I've got a reset style something like this:
* {
margin: 0;
padding: 0;
}
the result is:
<html xmlns="http://www.w3.org/1999/xhtml" style="margin: 0; padding: 0;">
<head style="margin: 0; padding: 0;">
<meta name="viewport" content="width=device-width" style="margin: 0; padding: 0;">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" style="margin: 0; padding: 0;">
<title style="margin: 0; padding: 0;">Actionable email</title>
<link href="styles.css" media="all" type="text/css" style="margin: 0; padding: 0;">
</head>
I can't think of any reason why you would want to apply styling to items in the head. It might be a good idea to turn this off by default and allow it to be turned on in the options.
Internal measurements have shown that this module can block node's internal event loop for about 200ms which is quite a long time.
Any chance you could break down internal async function blocks with setImmediate()
or process.nextTick
?
Thanks for this module, extremely useful for us. I'd like to request an additional option that'd remove the class attributes from elements which have the styles inlined.
Recommending a setting for use in email development that checks if margin: auto has been applied to an element. If so, we attempt to predictably center the element.
If the element is an img
it needs to be wrapped in a center
tag.
If the element is a table
then applying align="center"
suffices.
How about an option to allow a style tag in the head to be preserved and not inlined throughout the document? Perhaps a data attribute on the tag?
<style data-prevent-inline="true">
…
</style>
Currently, inline-css does not inline class-based attributes for an HTML tag if there is already a style attribute before inlining. Wouldn't it be more reasonable to merge/combine both style attributes?
Example:
CSS: p { color:red; }
HTML: <p style="font-weight:bold;">
Current Result: <p style="font-weight:bold;">
Desired Result: <p style="color:red;font-weight:bold;">
It would be a neat feature if we could somehow tell inline-css to ignore certain <link>
tags e.g. Google fonts link tag.
This would mean it leaves it as is on the page and skips over it
The following CSS rule:
background: linear-gradient(to bottom right, red, yellow);
translates to:
background: linear-gradient(tobottomright,red,yellow);
instead of:
background: linear-gradient(to bottom right,red,yellow);
Version: 2.2.1
the bgcolor
attribute is being filled in when the background color is set on a table elements via css.
However it only works if you write background-color: blue
It should also support the short form css of background: blue
Use something like https://www.npmjs.com/package/css-shorthand-expand to expand the properties before converting to table attributes.
I grabbed a copy of the project and ran gulp test
and one test failed. It seems to be because of how Windows handles line breaks because the CSS is the same. I ran the same code and tests on a Mac and all tests passed. Maybe the issue is upstream but I'll start here.
[08:05:51] Using gulpfile C:\src\inline-css-master\gulpfile.js
[08:05:51] Starting 'test'...
....................................
35 passing (404ms)
1 failing
1) inline-css Should inline css and preserve media queries:
AssertionError: expected '<html>\n<head>\n <style>\r\n@media screen {\r\n a {\r\n color: blue !important;\r\n background: red;\r\n }\r\n @font-face {\r\n font-family: \'Arial2\';\r\n }\r\n}\r\n</style>\n</head>\n<body>\n <p style="color: blue;">hi</p>\n</body>\n</html>\n' to be '<html>\n<head>\n <style>\n@media screen {\n a {\n color: blue !important;\n background: red;\n }\n
@font-face {\n font-family: \'Arial2\';\n }\n}\n</style>\n</head>\n<body>\n <p style="color: blue;">hi</p>\n</body>\n</html>\n'
+ expected - actual
<html>
<head>
- <style>
-@media screen {
- a {
- color: blue !important;
- background: red;
- }
- @font-face {
- font-family: 'Arial2';
- }
-}
+ <style>
+@media screen {
+ a {
+ color: blue !important;
+ background: red;
+ }
+ @font-face {
+ font-family: 'Arial2';
+ }
+}
</style>
</head>
<body>
<p style="color: blue;">hi</p>
at Assertion.fail (C:\src\inline-css-master\node_modules\should\lib\assertion.js:196:17)
at Assertion.prop.(anonymous function) (C:\src\inline-css-master\node_modules\should\lib\assertion.js:81:17)
at C:\src\inline-css-master\test\main.js:28:24
at bound (domain.js:250:14)
at runBound (domain.js:263:12)
at tryCatcher (C:\src\inline-css-master\node_modules\bluebird\js\main\util.js:26:23)
at Promise._settlePromiseFromHandler (C:\src\inline-css-master\node_modules\bluebird\js\main\promise.js:507:31)
at Promise._settlePromiseAt (C:\src\inline-css-master\node_modules\bluebird\js\main\promise.js:581:18)
at Promise._settlePromises (C:\src\inline-css-master\node_modules\bluebird\js\main\promise.js:697:14)
at Async._drainQueue (C:\src\inline-css-master\node_modules\bluebird\js\main\async.js:123:16)
at Async._drainQueues (C:\src\inline-css-master\node_modules\bluebird\js\main\async.js:133:10)
at Immediate.Async.drainQueues [as _onImmediate] (C:\src\inline-css-master\node_modules\bluebird\js\main\async.js:15:14)
[08:05:51] 'test' errored after 681 ms
[08:05:51] Error in plugin 'gulp-mocha'
Message:
1 test failed.
Like width
Right now, the preserveMediaQueries
option only applies to CSS inside of a document's <style>
tag, not to external CSS resolved via <link>
tags.
Allowing media queries inside external CSS to be transferred to the <style>
tag would allow for a much simpler workflow, assuming you're using a library like Ink, or any CSS library for writing HTML emails.
Spaces are mandatory inside CSS calc()
function, and should not be removed in inlining.
To reproduce:
const inlineCss = require('inline-css');
const html = `
<style>
div{width: calc(100% - 20px);}
</style>
<div/>
`;
inlineCss(html, {url: '/'}).then(function(html) { console.log(html); });
// => <div style="width: calc(100%-20px);"></div>
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.