jonkemp / inline-css

Inline css into an html file.
MIT License
429 stars 85 forks source link

Move media quesries inside a CSS file to a <style> element #113

Open TELUS-Alexander opened 2 years ago

TELUS-Alexander commented 2 years ago

My request is as follows:

When you have an HTML file that uses <link />, to a CSS file, and it has @media queries, have an option to move the media queries to a <style> element.

The reason for this request is that now if you have a media query inside the style.css file, it will either:

For example:

style.css

body {
  background-color: #FFFFFF;
}

@media all and (max-width: 600px) {
  background-color: #E5F0FF;
}

email.html

...
<head>
...
<link rel="stylesheet" href="style.css" />
...
</head>
<body>
...
</body>

After processing the file, via inline-css, with the option preserveMediaQueries: true the file would be as such:

email-inline-css.html

...
<head>
...
<style type="text/css">
@media all and (max-width: 600px) {
  background-color: #E5F0FF;
}
</head>
<body>
...
</body>

All the inline CSS rules would apply and the media queries would be moved to a <style> element.

Thank you for the great package.

MishaChernov commented 1 year ago

Any solutions?

bkilinc commented 1 year ago

Because of this issue I don't use linked style files. But it would be great if I can use. A workaround might be preprocessing the file to replace style links with style content. This should be a simple task but I could not find a ready-made solution for it.

r1m commented 1 year ago

This is what I did

  1. create an extracMediaQueriesCSS using the built-in packages (there are all already dependencies of this package) :
    
    import * as getHrefContent from "href-content";
    import * as getStylesheetList from "list-stylesheets";
    import * as mediaQueryText from "mediaquery-text";
    import { promisify } from "util";
    const getHrefContentAsync = promisify(getHrefContent);

export async function extractMediaQueriesCss(html: string, options) { const data = getStylesheetList(html, options); let mediaCss = []; for (const href of data.hrefs) { const linkedStyle = await getHrefContentAsync(href, options.url); mediaCss.push(mediaQueryText(linkedStyle)); }

return mediaCss.join("\n"); }


2. use that method to get the css then shamelessly inject it inside your html before calling inlineCSS

```js
  const inlineCssOptions = {
      url: `file://${templateFile}`,
     preserveMediaQueries: true,
     applyLinkTags: true,
  };
  const extraCss = await extractMediaQueriesCss(templateContent, inlineCssOptions);
  // inline the linked CSS mediaquery rules inside the html itself
  templateContent = templateContent.replace("</head>", `<style type="text/css">${extraCss}</style></head>`);
  templateContent = await inlineCss(templateContent, inlineCssOptions);
chenweigh commented 3 months ago

@TELUS-Alexander

My request is as follows:

When you have an HTML file that uses <link />, to a CSS file, and it has @media queries, have an option to move the media queries to a <style> element.

The reason for this request is that now if you have a media query inside the style.css file, it will either:

  • remain in the <link /> file, which is mostly not supported in email clients
  • be removed entirely

For example:

style.css

body {
  background-color: #FFFFFF;
}

@media all and (max-width: 600px) {
  background-color: #E5F0FF;
}

email.html

...
<head>
...
<link rel="stylesheet" href="style.css" />
...
</head>
<body>
...
</body>

After processing the file, via inline-css, with the option preserveMediaQueries: true the file would be as such:

email-inline-css.html

...
<head>
...
<style type="text/css">
@media all and (max-width: 600px) {
  background-color: #E5F0FF;
}
</head>
<body>
...
</body>

All the inline CSS rules would apply and the media queries would be moved to a <style> element.

Thank you for the great package.

How do I convert @media css to inline style ? Do you resolve it