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:
- Convert SCSS into CSS with jsonformatter.org/scss-to-css.
- Place CSS in
<head><style></style></head>
tags in your HTML. - 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
Set Maxlength in HTML Textarea
Can Div with Contenteditable=True Be Passed Through Form
Understanding Grid Negative Values
How to Render a Field Request Without Refreshing the Page
Change the Z Index of Flash Content
Twitter-Bootstrap Closing Alert Does Not Work
3 Column Layout (Fixed, Fluid, Fixed) with Minimum Width
How to Disable the Spell Checker on Text Inputs on the Iphone
CSS Display None and Opacity Animation with Keyframes Not Working
What's the Difference Between HTML's and CSS's Width Attribute
Border with a Transparent Centred Arrow
How to Change Bootstrap Select Arrows to Glyphicon
How to Select an Element That Has an Id Which Begins with a Digit