"Compile" CSS into HTML as Inline Styles

Compile CSS into HTML as inline styles

I think juice is what you're looking for.

Simply require it, then pass it your html and css and let it do the heavy lifting for you like this:

var juice = require('juice');
var inlinedcss = juice('<p>Test</p>', 'p { color: red; }');

It builds on a number of mature libraries including mootools' slick, and supports a broad range of selectors.

You may also be interested in node-email-templates, which is a nice wrapper for dynamic emails in node.

Convert css styles to inline styles with javascript keeping the style units

Couldn't find any way to do this using the built in getComputedStyle(). It also returned too many properties that I wasn't interested in. So I came up with a different approach. Basically to use the same function to loop through an element (and maybe all its children elements) and the use Element.matches() to get all the css rules that apply to the element and apply the properties as they were specified in the stylesheet.

I modified this answer a bit to get the rules from the stylesheet.

Has the added benefit that we can pull either from all the document stylesheets or just from a specific one that is needed for preparing the code to go into our content management systems's rich text editor.

function applyInline(element, recursive = true) {

if (!element) {
throw new Error("No element specified.");
}

const matches = matchRules(element);

// we need to preserve any pre-existing inline styles.
var srcRules = document.createElement(element.tagName).style;
srcRules.cssText = element.style.cssText;

matches.forEach(rule => {
for (var prop of rule.style) {

let val = srcRules.getPropertyValue(prop) || rule.style.getPropertyValue(prop);
let priority = rule.style.getPropertyPriority(prop);

element.style.setProperty(prop,val,priority);
}
});

if (recursive) {
element.children.forEach(child => {
applyInline(child, recursive);
});
}
}

function matchRules(el, sheets) {
sheets = sheets || document.styleSheets;
var ret = [];

for (var i in sheets) {
if (sheets.hasOwnProperty(i)) {
var rules = sheets[i].rules || sheets[i].cssRules;
for (var r in rules) {
if (el.matches(rules[r].selectorText)) {
ret.push(rules[r]);
}
}
}
}
return ret;
}

CSS style to inline style via JavaScript

You can do something like this:

function applyStyle(el) {
s = getComputedStyle(el);

for (let key in s) {
let prop = key.replace(/\-([a-z])/g, v => v[1].toUpperCase());
el.style[prop] = s[key];
}
}

let x = document.getElementById('my-id');
applyStyle(x);

Where x is the element you want to apply the style to.

Basically this function gets the computed style of the element and then copies each property (like padding, background, color, etc.) to the inline style of the element.

I don't know why you need to do this, but it's a really dirty approach in my opinion. I would personally advise against it.

Format inline CSS with Python

Try the following approach:

from bs4 import BeautifulSoup
from cssutils import parseStyle

with open('input.html') as f_html:
soup = BeautifulSoup(f_html, 'html.parser')

for textarea in soup.find_all('textarea', style=True):
style = parseStyle(textarea['style'])
style['width'] = '200px'
textarea['style'] = style.cssText.replace('\n', ' ')

with open('output.html', 'w', encoding='utf-8') as f_html:
f_html.write(str(soup))

So if your HTML is:

<html>
<body>
<textarea id="123" attributeX="4" attributeY="5" style="width:159px; height:50px;"></textarea>
<textarea id="456" attributeX="4" attributeY="5" style="width:135px; height:50px;"></textarea>
<textarea id="789" attributeX="4" attributeY="5" style="width:177px; height:50px;"></textarea>
<textarea id="789" attributeX="4" attributeY="5"></textarea>
</body>
</html>

The output would become:

<html>
<body>
<textarea attributex="4" attributey="5" id="123" style="width: 200px; height: 50px"></textarea>
<textarea attributex="4" attributey="5" id="456" style="width: 200px; height: 50px"></textarea>
<textarea attributex="4" attributey="5" id="789" style="width: 200px; height: 50px"></textarea>
<textarea attributex="4" attributey="5" id="789"></textarea></body>
</html>

Here the final <textarea> is unchanged as there was no style. If required, this could be added as follows:

from bs4 import BeautifulSoup
from cssutils import parseStyle

with open('input.html') as f_html:
soup = BeautifulSoup(f_html, 'html.parser')

for textarea in soup.find_all('textarea'):
if 'style' in textarea.attrs:
# Update existing style
style = parseStyle(textarea['style'])
style['width'] = '200px'
textarea['style'] = style.cssText.replace('\n', ' ')
else:
# Add missing style
textarea['style'] = 'width: 200px; height: 50px'

with open('output.html', 'w', encoding='utf-8') as f_html:
f_html.write(str(soup))

How to convert it SCSS inline styles in your HTML

Here is your converted HTML:

<!DOCTYPE html>
<html lang="en">

<head>
</head>

<body style='background:#222; color:#fff; font-family:"Roboto", serif'>

<div class="grid" style="display:flex; margin:0 auto; max-width:1200px">

<div class="product" style="margin-right:0; max-width:333px; width:99%" width="99%">
<div class="product-image" style="height:100%; max-height:225px; max-width:100%" height="100%">
<a href="https://www.jdsports.se/product/nike-air-force-1-shadow-womens/393242_jdsportsse/" target="_blank">
<img style="background-position:center; background-repeat:no-repeat; background-size:cover; height:100%; width:100%; background-image:url(https://i.imgur.com/9pdOpoF.png)" height="100%" width="100%">
</a>
</div>
<div class="product-description" style="align-items:center; display:block; margin-top:20px; max-width:100%">
<h1 style="-webkit-box-orient:vertical; -webkit-line-clamp:2; display:-webkit-box; font-size:1rem; height:40px; margin-bottom:10px; overflow:hidden; text-align:center; text-overflow:ellipsis; text-transform:uppercase" height="40" align="center">
Nike Air Force 1 Shadow Womens sfg sdfg sdf gdfs sdf
</h1>
<div class="brand-wrapper" style="-webkit-box-pack:center; -webkit-justify-content:center; align-items:center; display:flex; flex-direction:column; justify-content:center">
<span class="brand" style="margin-bottom:0.5rem">(Jdsports)</span>
<span class="id">ID 2200</span>
</div>
</div>
</div>
</div>

</body>

</html>

How I converted it:

  1. Convert SCSS into CSS with jsonformatter.org/scss-to-css.
  2. Place CSS in <head><style></style></head> tags in your HTML.
  3. Run HTML in Premailer HTML styles inliner.

Make css styles inline into html elements

You can use https://github.com/milkshakesoftware/PreMailer.Net

 string htmlSource = File.ReadAllText(@"C:\Workspace\testmail.html");

var result = PreMailer.MoveCssInline(htmlSource);

result.Html // Resultant HTML, with CSS in-lined.
result.Warnings // string[] of any warnings that occurred during processing.

How to force webpack to put the plain CSS code into HTML head's style tag?

I've done this before only using style-loader that by default will add your css as style inline at <head> tag. This won't generate any output css file, this just will create one/multiple style tags with all you styles.

webpack.config.js

module.exports = {
//... your config

module: {
rules: [
{
test: /\.scss$/, // or /\.css$/i if you aren't using sass
use: [
{
loader: 'style-loader',
options: {
insert: 'head', // insert style tag inside of <head>
injectType: 'singletonStyleTag' // this is for wrap all your style in just one style tag
},
},
"css-loader",
"sass-loader"
],
},
]
},

//... rest of your config
};

index.js (entry point script)

import './css/styles.css';


Related Topics



Leave a reply



Submit