npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

css-in-console

v2.0.0

Published

Naive and simplistic styling of terminal text using “CSS”. Provides `console.log`/… alternatives with partial `%c` support.

Downloads

4

Readme

import { log, style } from "css-in-console";
const css= style`
	@import "./example.css";
	.h1{ color: red; }
	.h1::before{ content: "# "; }
	.li{ display: list-item; }
	.b{ font-weight: bold;}
`;
log("%cHeading 1", css.h1);
log("%cParagraph & code style –", css.p,
	"let's say they are defined in the file %c`./example.css`%c.",
	css.code, css.unset);
log("UL %c↓%c:", "color:green", css.unset);
log("%cLI (by default %cstarts%c with `- `)",
	css.li, css.b, css.unset,
	"…you can use `list-style-type` to change it."
);

css-in-console

css-in-console is a library that allows you to style terminal outputs in JavaScript/TypeScript code using a CSS-like syntax. Primarily, this can be used to apply certain text formatting and its colors. Furthermore, some additional CSS structures are also supported (see below).

The library offers alternatives to native functions console.log/util.format/…. In the exported functions (log/error/format/formatWithOptions), you can apply styling according to Styling console output.

Installation

You can install the css-in-console library using your favorite package manager.

For example, with npm:

npm install css-in-console --save

If you are OK with only basic styling (no at-rules, …), you can use the 1.x.y version:

npm install css-in-console@1 --save

Usage

First, you need to import the required functions from the css-in-console library:

import { format, formatWithOptions, log, error, style } from 'css-in-console';
// OR
import log from 'css-in-console';

Basic usage

You can use the log and error functions to print styled messages to the console. For example:

log("%cRed text", "color:red");
error("%cGreen text", "color:green");

…or prepare formatted text:

console.log(format("%cBlue text", "color:blue"));
console.log(formatWithOptions({ colors: true }, "%cBlue text", "color:blue"));

The exported functions process the CSS (%c expression) in the first step and then return to the corresponding native functions:

Important consequence: %c is processed firstly so instead of log("%i%c", 5, "color:red") you must reorder arguments and so use log("%i%c", "color:red", 5)! (log("%i%c", A, B)console.log("%i★", B), where ★ is text with apllied styling or empty depends on A)

Defining CSS-like rules

You can also use the style/css or log.style/log.css helpers to prepare styling rules (they are aliases for the same function). Originally, there was only style, but other options (mainly log.css) seem to be convenient when you want to use css variable and use syntax highlight in your editor, e.g.:

const css= log.css`
	.example{ color: red; }
`;
log("%cExample", css.example);

Documentation and Examples

For library documentation and examples, see:

In the following we will introduce the supported CSS constructs. Beware of using ‘real’ CSS! Treat the syntax more like keywords, the library is not intended to implement a CSS parser. CSS at-rules and selectors are supported only when used in style/css/log.css functions.

CSS at-rules

This library mimic At-rules | MDN behaviour and supports:

  • Supported syntax is only @import 'url';, you can provide full path or relative to main script (internally uses argv[1]).

    const importedStyles = style("@import './styles.css'");

    …there is also another limitation, the @import is supported only inside style/css/log.css functions.

    For original documentation visits @import - CSS: Cascading Style Sheets | MDN.

  • …so, only color is supported:

    @media (color){ … }
    @media not (color){ … }

    …in case of terminal the color means ANSI escape codes. Meaning, colors and font styling.

    For original documentation visits @media - CSS: Cascading Style Sheets | MDN.

    Note 1: Experimentaly, you can use (--terminal-stdout)/not (--terminal-stdout) to style terminal stdout/stderr output differently.

    Note 2: Also logical CSS keywords (and/or) are experimentaly supported. Eg. @media (color) and (not (--terminal-stdout))….

  • The implementation in this library is very similar to the specification.

    @counter-style thumbs {
    	system: cyclic;
    	symbols: 👍;
    	suffix: " ";
    }
    .li {
    	display: list-item;
    	list-style: thumbs;
    }

    You can utilize the symbols, suffix, prefix, pad, and negative properties in a manner similar to the CSS specification.

    Additionally, you can specify system values of fixed, cyclic, numeric and alphabetic, just like in CSS. Furthermore, you can use library-specific --terminal-* systems such as --terminal-datetime (--terminal-date and --terminal-time) as illustrated in the list-style examples below. The cyclic ⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏ symbols are available through the --terminal-spin property.

    Predefined counters include decimal and --terminal-* (datetime/date/time and spin).

    log("%c@counter-style", `display: list-item;
    	list-style: decimal`); //= 1. @counter-style
    log("%c@counter-style", `display: list-item;
    	list-style: --terminal-spin`); //= ⠋ @counter-style
    log("%c@counter-style", `display: list-item;
    	list-style: --terminal-datetime`); //= 2023-05-05T10:28:18.696 @counter-style
    log("%c@counter-style", `display: list-item;
    	list-style: --terminal-date`); //= 2023-05-05 @counter-style
    log("%c@counter-style", `display: list-item;
    	list-style: --terminal-time`); //= 10:28:18.697 @counter-style

    …you can extend these with extend syntax system: extend --terminal-time;.

    To utilize --terminal-* date and time counters, you can use --terminal-mask: <symbols> <mask>;. Symbols contains two characters (first/second represents ‘remove’/‘keep’), see example:

    --terminal-mask: "01" "111111CSS001"

    …this mask applied to “Hello World!” leads to “Hello CSS!”.

    For more information, see:

CSS selectors

Classes are the preferred selectors because they are intuitive as object properties:

const css= log.css`
	.example{ … }
`;
log("%cExample", css.example);

…it is also convenient not to use kebab-case names.

Technically, it is possible to use ID selectors and HTML elements. But these are escaped using .replaceAll(/[\.#]/g, "") and (so far?) no practical effect from using them.

In term of pseudo-elements, only ::before/::after are supported.

Other CSS selectors are not supported (and probably have no use in the terminal).

CSS rules

As mentioned above, mostly more keywords than syntax. You can use initial value to sets the initial value of any property.

  • Rules marked with {★} are ignored when the colors are not supported.
  • Rules marked with {!::} are not supported for ::before/::after.
  • color: <color> / background: <color> {★}: see supported colors
  • margin-left: <number> / margin-right: <number> {!::}: inserts spaces before/after the string. Measurements <number><measurement> can also be used (e.g. ch makes sense). But in the post-processing is ignored.
  • padding-left: <number> / padding-right: <number> {!::}: For now just alias for margin-*
  • font-style: italic {★}
  • font-weight: bold {★}
  • text-decoration: underline|line-through {★}
  • animation: blink {★}
  • tab-size: <number> {!::}: all tabs will be replaced with given number of spaces (default: 7)
  • display: none {★}
  • display: list-item {!::}: basic implementation of list-style-type - CSS: Cascading Style Sheets | MDN
    • list-style-type: "<string>": defaults to "- "
    • list-style-type: <counter> (see @counter-style above)
    • list-style: *: just an alias for list-style-type
  • content: *: supported only for ::before and ::after, library implements only basic of content - CSS: Cascading Style Sheets | MDN
    • content: "<string>"
    • content: <counter/string combination>: you can use counter()
  • counter-increment: only <counter>/<counter> <integer> values are supported
  • counter-reset: only <counter>/<counter> <integer> values are supported

Options under consideration for next release(s)

  • somehow determine dark/light background ⇒ @media (prefers-color-scheme: dark) (similarly for light)
  • width/text-overflow/white-space
  • display:block ⇒ append "\n"?
  • text-align
  • another pseudo-elements e.g. ::first-letter, ::marker, …
  • another at-rules e.g. @supports, …
  • display:table/display:table-row: more likely not, there are better ways to use (for example console.table - npm)
  • position:absolute/position:fixed: starts rewritable mode + @keyframes/animation (for spinners, progress bars, etc.) … more likely not
  • margin-*/padding-*: now work the same