Numl - Alternative markup and styling language for the web

Hello! My name is Andrey, I have been professionally developing web interfaces for over 11 years and for the last year I have been developing the Numl project, which can be called a markup and styling language for the web. In this article, I'll show you how, in an attempt to overcome a number of CSS features and simplify the layout of web projects, we ended up with a whole language that not only satisfied all our styling needs, but also allowed us to reduce the amount of JS code and improve accessibility.





For a start, briefly about Numl and how it might be of interest to developers.



Numl is a markup language that combines the functions of a CSS framework , a JS framework without composition and a Design System , and provides a set of pre-built elements, each of which has an extensive set of properties for customization. The language is based on the native Custom Elements browser API from the Web Components specification, and is compatible with popular JS frameworks such as Vue , Svelte , Angular, and React . A distinctive (and I would even say "unique") feature of Numl is that it generates all the styles for the interface at runtimeto get the most out of your CSS and achieve great flexibility in styling and customizing elements. This article is the answer to the question of how it happened and why this approach deserves the right to life.



Last week, July 4th, the project turned exactly one year old and it has long passed the proof of concept stage . A large project Sellerscale and a browser extension from Sellerscale are written on it . Also, using Numl, several more sites have been created, including their own landing page and Storybook. A complete set of links will be at the end.





Sellerscale dashboard. Stack: VueJS, Numl





Sellerscale extension. Stack: Svelte, Numl



Numl ,   HTML/CSS , -, CSS ARIA. , CSS , , -. Utility-First CSS? .



, Numl, numl.design, Storybook , Numl REPL.





22 , , Turbo Pascal, , , . , - . - HTML/CSS, JS- . , . , , , , CSS-, .



, , Modifier Value ( ). , , . , .



, , , CSS , . . , -, , . - , , , , . " CSS", :



  • CSS . , Grid, . , ( ), position, top/right/bottom/left transform, JS, .
  • CSS , . , box-shadow (/ ), transform ( ) .. , JS-, .
  • , . !important .
  • , . .cls:hover .cls:focus . , , . CSS (.cls:hover:not(:focus) ..), , , . , - , .
  • , . , (.btn.fancy-btn) , " ". , , , "/ hover ". " ", ( touch-) CSS.
  • CSS Media Queries (@media not all and (hover: none)) , .
  • CSS+HTML, CCSOM+DOM . , , , .
  • JS, CSS- . . runtime - getComputedStyle(), .
  • CSS . , .


, . , - . , breakpoints CSS-.



, , β€” . CSS , - , , CSS .



, .





, CSS, . , CSS . , , .



. , , MyGrid MyFlex display , , item- (basis/width/height) - ( ) . basis, width, height , .



size text, . size font-size/line-heigh, ( css ), , ..



inline-. , , , , , .



, , DX (Developer Experience). / .



- , . .



. . , . , . :



<template>
    <div :class="classes" :style="styles">
        <slot></slot>
    </div>
</template>


, !



.. . . :



<my-btn>
    Button
    <my-popup>Popup content</my-popup>
</my-btn>


, . , . MyDropdown, . , , .



, , , , , , ( ). - - my-grid, . Custom Elements. , ! Custom Elements, Open Source NUDE Elements, Numl. nu-.



: NUDE – JS-, Numl .

. Numl . inline-. CSS . CSS . , : nu-grid columns 1fr 1fr. , columnsAttr('1fr 1fr'), :



export function columnsAttr(val) {
    return {
        'grid-template-columns': val,
    };
}


CSS:



nu-grid[columns="1fr 1fr"] {
    grid-template-columns: 1fr 1fr;
}


… <style>, <head>. , CSS, .



( ), , , CSS.



, , - CSS ( Atomic CSS), CSS-in-JS , CSS .





CSS, , .



, Numl . , <nu-block border> :



nu-block[border] {
    border: var(--nu-border-width) solid var(--nu-border-color);
}


, .



place. , .



<nu-card>
    <nu-el place="outside-top">Float element</nu-el>
</nu-card>


REPL



grid/flex-, float-, fixed sticky. CSS .



. , transform :



<nu-card move="2rem 2rem" scale="2">
    Card
</nu-card>


REPL



, , :



<nu-block width="10x"></nu-block>


REPL



x β€” gap.



gap'. Flexbox, :



<nu-flex gap="2x 1x" flow="row wrap">
    <nu-block>Item 1</nu-block>
    <nu-block>Item 2</nu-block>
    <nu-block>Item 3</nu-block>
</nu-flex>


REPL



Storybook.



. API . - Numl , . , Numl .



?



, , . , β€” . CSS , . , 4 , , , , . : .



, . , , , . .



Numl. - <nu-attrs>, -. , . , :



<nu-pane>
    <nu-attrs for="btn" color="special"></nu-attrs>
    <nu-btn>Button 1</nu-btn>
    <nu-btn>Button 2</nu-btn>
</nu-pane>


REPL



, color="special". , ( !) <nu-attrs>, . <nu-attrs> , , . , .



- , , , . , ( ).



<nu-attrs> .





. , - , , . ( 0 359 HSL) Custom Properties , .



. (, ), , .





-. Sellerscale



, :



  • . ( WCAG Contrast Ratio).
  • , , .
  • .
  • API .
  • , .
  • , (, )


, . , . : tenphi.me ( ) Storybook. CodePen Numl.





numl.design









Storybook



, , hue(), , , Numl HSC (, , ). .





. Numl. tenphi.me



Numl -, .





, , Numl. ...



( )



. , . ( ) : breakpoint', , | ( ), - . breakpoint' , :



<nu-root responsive="60rem|40rem">
    ...
</nu-root>


(, ). - . , |:



<nu-root responsive="60rem|40rem">
    <nu-grid columns="repeat(4, 1fr)|1fr 1fr|1fr">
        ...
    </nu-grid>
</nu-root>


REPL



. , . .



, . , , .





Sellerscale





, , . , , ( ), .



:



<nu-card shadow="0 :hover[1]">
    Content
</nu-card>


REPL



, , , .



, :



<nu-card>
    <nu-block color="^ text :hover[special]">Content</nu-block>
</nu-card>


REPL



. , :



nu-card[color="^:hover[special]"]:hover {
    color: var(--nu-spcial-color);
}
nu-card[color="^:hover[special]"]:not(:hover) {
    color: var(--nu-text-color);
}


. ? Numl . , ( text). CSS , , ! , , , .



is-. :



<nu-btn is-loading>
    <nu-el show="^ y :loading[n]">Submit</nu-el>
    <nu-icon name="loader" show="^ n :loading[y]"></nu-icon>
</nu-btn>


REPL





, , CSS :



  • , , .
  • " ", .
  • .
  • . , , hover. , , , hover touch-. ( Numl, API).
  • Media Queries.
  • Numl . runtime , , , getComputedStyle(). .
  • . , . .


, , . :)



, , . : .



.



, ? , HTML, <button> .



Numl, . . Numl Behaviors. . , nx- .



<nu-el nx-action>Button</nu-el>


REPL β€” nu-el.



, nu-btn . Numl 35-. . , , , Markdown Numl!





Numl Storybook: Markdown->Numl





. , , , . ( !)



- , - .



Numl ARIA, .



. . , ID, . , ID button-23.



Numl . ID , . , . , ID, ID, Numl ID. , , .



<nu-region labelledby="label">
    <nu-block id="label"></nu-block>
</nu-region>


REPL



HTML, , .



Numl aria- . , , , ( aria-), .



:



<nu-btn label="Turn on lights">
    <nu-icon name="sun"></nu-icon>
</nu-btn>


. , .



, Numl ARIA , .





Numl - . , CSS JS "", . , , :



  • . Numl 40, , , . , , , , Numl - JS . .
  • . Numl , , , . , , UX .
  • SSR. Numl SSR , . . SEO , prerender.io.
  • . Numl , Custom Elements, Custom Properties CSS Grid. Numl Edge 15+ , ( ).
  • Numl - , JS-. , . .
  • Numl - , . .


, Numl , , :



  • . , "-", , .
  • DX, -. HTML, . (// / )
  • " " , .
  • . " CSS". .
  • CSS- ( TailwindCSS) , .
  • , .
  • - , .
  • ;)


Numl , . , , .







PRE-BETA (v0.11). , , experimental v1 (, ). 2020.



:



  • 1100+
  • 200+ npm
  • ~1300
  • 85 GitHub (, , !)


Numl, , , , . ( !) .



! . :





Numl:





,



REPL, Numl.



, , , JS CSS:






All Articles