
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
html-by-css
Advanced tools
Generate html by writing css.
npm i html-by-css
import generate from 'html-by-css';
const source = `
ul#list {
list-style: none;
margin: 0;
padding: 0;
& li.item*3 {
padding: .5rem;
:is(a[href="#"]) {
content: Link;
color: inherit;
}
}
}
`;
const { html, css } = generate(source);
HTML
<ul id="list">
<li class="item">
<a href="#">Link</a>
</li>
<li class="item">
<a href="#">Link</a>
</li>
<li class="item">
<a href="#">Link</a>
</li>
</ul>
CSS
/* legacy: false (default) */
ul#list {
list-style: none;
margin: 0;
padding: 0;
& li.item {
padding: .5rem;
:is(a[href="#"]) {
color: inherit;
}
}
}
/* legacy: true */
ul#list {
list-style: none;
margin: 0;
padding: 0;
}
ul#list li.item {
padding: .5rem;
}
ul#list li.item :is(a[href="#"]) {
color: inherit;
}
postcss to parse and walk through source.content on non-pseudo elements.emmet syntax.postcss-nesting plugin to transform into legacy, non-nested CSS.{ html, css }.The nesting should be prepared using the current w3 CSS Nesting specification. The most important concept is that a nested selector must start with a symbol.
.foo {
/* ❌ invalid */
span {
color: hotpink;
}
/* ✅ valid */
& span {
color: hotpink;
}
/* ❌ invalid */
span & {
color: hotpink;
}
/* ✅ valid */
:is(span) & {
color: hotpink;
}
}
If you wish to collapse the nesting for the CSS output, set legacy: true in the options. This uses postcss-nesting with the default options.
const { html, css } = generate(source, { legacy: true });
If you want to set your own options, provide your own version of the postcss-nesting plugin and configure.
import nesting from 'postcss-nesting';
import generate from 'html-by-css';
const postcssPlugins = [nesting({
noIsPseudoSelector: true
})];
const { html, css } = generate(source, { plugins: postcssPlugins });
Warning
Do not use
legacy: truewith your ownpostcss-nestingconfiguration. The internal (legacy) usage will run first. Either do not declare or explicitly setlegacy: false. This is only when using a custompostcss-nesting, all other plugins can be used withlegacy: true.
You can include additional postcss plugins. Example below helps with removing duplicate declarations.
import dedupe from 'postcss-discard-duplicates';
import generate from 'html-by-css';
const postcssPlugins = [dedupe()];
const { html, css } = generate(source, { plugins: postcssPlugins });
This is helpful if you have several similar elements with different contents.
ul#list {
& li.item {
& a*0 {
color: inherit;
}
& a[href="/home"] {
content: Home;
}
& a[href="/about"] {
content: About;
}
& a[href="/contact"] {
content: Contact
}
}
}
Note
The use of
a*0says write the styles found here, but don't write HTML. When you use this, the represented node and it's children will not be written as HTML.
To create multiple elements, use emmet syntax.
ul {
li*5 {
/* Makes 5 <li/> elements */
}
}
This li*5 selector is not valid CSS and is transformed during processing to li.
To add text content, use the content property on non-pseudo elements.
main {
& h1 {
content: Hello world!;
}
}
<main>
<h1>Hello world!</h1>
</main>
Note
There are no quotes around the string. Adding quotes would include the quotes in the output.
The content property is not valid on non-pseudo elements and is removed from these declarations during processing.
npm t
cheerio to traverse HTML in tests.@projectwallace/css-analyzer to analyze returned CSS.There's definitely some cases not covered in the tests yet.
content prop and nested selector (both text and children).:nth-child(), :checked).Your scientists were so preoccupied with whether they could, they didn't stop to think if they should.
There's a few projects out there that are HTML preprocessors (Haml, Pug) which have their own (sometimes CSS-like) syntax. I wondered if we could get closer to just writing CSS to produce HTML. With the new nesting specification and the power of postcss, it looks like we can!
FAQs
Generate html by writing css
We found that html-by-css demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.