css-in-console
v2.1.0
Published
Naive and simplistic styling of terminal text using “CSS”. Provides `console.log`/… alternatives with partial `%c` support.
Downloads
95
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:
log
/error
⇒console.log
/console.error
format
/formatWithOptions
⇒util.format
/util.formatWithOptions
…Important consequence:
%c
is processed firstly so instead oflog("%i%c", 5, "color:red")
you must reorder arguments and so uselog("%i%c", "color:red", 5)
! (log("%i%c", A, B)
⇒console.log("%i★", B)
, where ★ is text with apllied styling or empty depends onA
)
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:
- documentation (generated from TypeScript definition file)
- examples
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 usesargv[1]
).const importedStyles = style("@import './styles.css'");
…there is also another limitation, the
@import
is supported only insidestyle
/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
, andnegative
properties in a manner similar to the CSS specification.Additionally, you can specify
system
values offixed
,cyclic
,numeric
andalphabetic
, just like in CSS. Furthermore, you can use library-specific--terminal-*
systems such as--terminal-datetime
(--terminal-date
and--terminal-time
) as illustrated in thelist-style
examples below. The cyclic⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏
symbols are available through the--terminal-spin
property.Predefined counters include
decimal
and--terminal-*
(datetime
/date
/time
andspin
).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
syntaxsystem: 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 colorsmargin-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 formargin-*
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 | MDNlist-style-type: "<string>"
: defaults to"- "
list-style-type: <counter>
(see@counter-style
above)list-style: *
: just an alias forlist-style-type
content: *
: supported only for::before
and::after
, library implements only basic of content - CSS: Cascading Style Sheets | MDNcontent: "<string>"
content: <counter/string combination>
: you can usecounter()
counter-increment
: only<counter>
/<counter> <integer>
values are supportedcounter-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 forlight
) 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 notmargin-*
/padding-*
: now work the same