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
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.
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
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';
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
)
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);
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.
This library mimic At-rules | MDN behaviour and supports:
-
@import
— To include an external style sheet. (expand for more)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.
-
@media
— To provide styles when terminal (not) supports “colors”. (expand for more)…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))…
. -
@counter-style
— To define specific counter styles that are not part of the predefined set of styles. (expand for more)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:
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).
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 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 | MDN-
list-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 supported -
counter-reset
: only<counter>
/<counter> <integer>
values are supported
- 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 not -
margin-*
/padding-*
: now work the same