Let’s first look at our final goal, how we can describe the code:

import React from "react";

export default() = > (<button inlist="bg:#f00; @md:display:none; hover:radius:8px; radius:4px">I'm a button</button>
);
Copy the code

In this file, we “don’t seem to have introduced any libraries”, as with inline styles, implementing style descriptions, media queries, pseudo-classes, and customizing style names such as BG and RADIUS.

cssin

Cssin is a highly customizable low-level CSS-in-JS framework that gives you all the building blocks you need to build custom designs without any annoying styles, all the syntax you can use for inline styles, and other extended syntax.

Most CSS frameworks do too much. They come with all sorts of pre-designed components such as buttons, cards, and alerts that may help you move quickly initially, but can cause more pain when your site stands out using custom designs.

Cssin is different.

Cssin provides low-level utility classes instead of fixed, pre-designed components, allowing you to build fully custom designs without leaving JS.

Each of the same style values generated by cSSIN can be referenced repeatedly rather than recreated.

concept

We tried a lot before using cssin, CSS \less\ SCSS, tailwindCSS, styled-components and other css-in-js schemes. TailwindCSS is the most suitable for production needs, from which we learn a lot of things and ideas; But these style schemes don’t really solve the problem for the author:

Describe my style briefly and efficiently, without leaving js; We certainly don’t give up any of the CSS features

Css-in exists to solve this kind of problem

Aimed at custom

All cSSIN styles are customizable, and CSSIN allows you to customize it. This includes color, border size, font size, spacing utilities, breakpoints, shadows and any CSS styles.

Cssin is written in pure Typescript and requires no configuration of the project framework, which means you can easily get the full functionality of a real programming language.

Cssin extends the implicit style of pseudo-class and media queries, and supports custom property names and custom components.

Cssin is not just a CSS-in-JS framework, it is an engine for creating design systems.

light

  • Only 2 KB (gzip)
  • Each style is cached for higher performance styling
  • You can use it in any framework, like React, Vue, Stencil

The installation

$ npm i cssin --save
Copy the code

Let’s look at the presentation

example: navar.workos.top

Before any configuration, cSSIN’s syntax and introverted style are consistent

import React from "react";
import cssin from "cssin";

// Set a global css-value
document.body.style.setProperty("--button-color"."#fff");

export default() = > {return (
    <div
      className={cssin`background-color:#f66; hover:background-color:#f33; padding:8px; color:#000; border:2px solid #f33; @md:border-radius:4px; `} >
      Button
    </div>
  );
};
Copy the code

It looks good, a bit like inline style, but a bit different, as it seems to describe pseudo-classes and media queries directly, and the code is less streamlined.

Ok, we’ll end up with a simple configuration to make the style description look like this:

import React from "react";
import cssin from "cssin";

export default() = > {return (
    <div className={cssin`btn:#f33.8px; hover:bg:#f33; @md:radius:4px; `} >
      Button
    </div>
  );
};
Copy the code

Or extreme simplicity:

import React from "react";
import cssin from "cssin";

export default() = > {return <div className={cssin`button`} >Button</div>;
};
Copy the code

Even the cSSIN package is omitted:

import React from "react";

export default() = > {return <div inlist="button">Button</div>;
};
Copy the code

We will take steps to reach the final step.

Cssin can probably be described in one paragraph

Let’s review our initial code block:

export default() = > {return (
    <div
      className={cssin`background-color:#f66; hover:background-color:#f33; padding:8px; color:--button-color; border:2px solid #f33; @md:border-radius:4px; `} >
      Button
    </div>
  );
};
Copy the code

The code above is a bit like inline, but a bit different because it allows for pseudo classes and better customization. Let’s step through:

  • Write CSS styles the same way you write inline styles, such as:background-color: #f66; padding: 4px;
  • Use the pseudo class directly, which precedes the attribute name:Segmentation, such as:hover:background-color=#f33
  • You can directly describe media query and other functions used by media query objects@At the beginning, as:@md:border-radius=4px

Other rules:

  • If only the property name, then it would be a component, such asbutton;
  • If the value is oneA singleCSS variables, such ascolor:--button-color; Equivalent tocolor:var(--button-color);
  • use!said! important, such ascolor: #f00!; Equivalent tocolor: #f00 ! important
  • If only the attribute name is available and the.At the beginning, then, are references to native CSS styles such as.button;
  • If you include{}To indicate that this is a pure CSS, it will be inserted into the global style, as inbody { margin:0px; }

Those are all the rules of CSSIN

Here is the full property expression: @[media query]:[pseudo-class name]:[property name]:[property value];

Here’s the full syntax:

// When the media query is greater than 760px, mouse over, stroke equals #f00;
cssin`@md:hover:border:1px solid #f00; `;
Copy the code

Why not just write inline style?

  1. Style styles do not fully describe CSS functions, such as media queries, pseudo-classes, and so on.
  2. Styles cannot customize shorter style sets, combinations of style sets, or nesting;
  3. Inline styles can’t reference className directly, so we usually need to write CSS files that set className and style;
  4. And the default priority is higher than CSS, CSS and inline style mixing needs to pay attention to the priority;

Cssin still generates CSS styles at the end of the day, so you don’t have these problems

If you prefer to write the style attribute

Some people prefer to write style attributes, but a pain point in style is the inability to implement pseudo-classes or media queries.

Cssin is lightweight enough that we could just use its pseudo-class or media query features to write project-style items in conjunction with the Style property.

Note, however, that the attribute weight written in style is by default higher than that in className, so it needs to be added! important:

import React from "react";
import cssin from "cssin";

export default() = > {return (
    <div
      className={cssin`hover:background:#f00 !important; `}style={{
        background: "#00f",
        fontSize: "20px}} ">
      Button
    </div>
  );
};
Copy the code

Since this pattern is so common, it can be used in CSSIN! Direct expression! important:

. exportdefault() = > {return (
    <div
      className={cssin`hover:background:#f00! ; `}style={{
        background: "#00f",
        fontSize: "20px}} ">
      Button
    </div>); }; ZCopy the code

Customize custom styles

Like many CSS frameworks, CSSIN allows you to customize style sets, which can be described in shorter statements

Cssin has an addSheets property for adding style maps

We now agree to:

background-color:#f66; hover:background-color:#f33; padding:4px; color:--button-color; border:2px solid #f33; @md:border-radius:8px;

To:

btn:#f33, 4px; hover:bg:#f33; @md:radius:8px;

import React from 'react';
import cssin, { addSheets } from 'cssin';

// Add a custom style set
addSheets({
  bg: (v) = > `{ background-color: ${v}; } `.radius: (v) = > `{ border-radius: ${v}; } `.btn: (v) = > {
    const values = v.split('; ');
    return {
      `{ background-color: ${values[0]}; padding:${values[1]}; color:var(--button-color); } `}}});// Use custom styles
export default() = > {return <div className={cssin`btn:#f33.4px; hover:bg:#f33; @md:radius:8px; `} >Button</div>;
};
Copy the code

With CSSIN, we don’t need CSS code, so we can reduce resource requests on the first screen of the project.

In addition to simplifying development, custom styles can also reduce the amount of JS code, resulting in relatively fewer packaged resources.

Custom media enquiries

Cssin defaults to four size levels of media queries, and device-based media queries, which we can override or create new rules

Note that we have agreed that only those beginning with @ are media query objects

// The default media query
addSheets({
  "@sm": (v: string) = > `@media (min-width: 640px) {${v}} `."@md": (v: string) = > `@media (min-width: 768px) {${v}} `."@lg": (v: string) = > `@media (min-width: 1024px) {${v}} `."@xl": (v: string) = > `@media (min-width: 1280px) {${v}} `."@ios": (v: string) = >
    `@media (min-width: ${device.isIos ? "0px" : "9999px"}) {${v}} `."@android": (v: string) = >
    `@media (min-width: ${device.isAndroid ? "0px" : "9999px"}) {${v}} `."@native": (v: string) = >
    `@media (min-width: ${device.isNative ? "0px" : "9999px"}) {${v}} `."@pc": (v: string) = >
    `@media (min-width: ${device.isPc ? "0px" : "9999px"}) {${v}} `
});
// We override @md and create an @xxl
addSheets({
  "@md": v= > `@media (min-width: 800px) {${v}} `."@xxl": v= > `@media (min-width: 1920px) {${v}} `
});
Copy the code

Using media query, in the following example the screen width is greater than 800px, the button width is 200px, and hidden in the native end

import React from "react";
// You only need to wrap the declaration around one word
export default() = > {return (
    <div inlist="width:100px; height:50px; @md:width:200px; @native:display:none;">
      Button
    </div>
  );
};
Copy the code

Custom components

We want to abbreviate this code to a more elaborate component, which is actually a set of styles

Set custom components, because sheets is a simple table of objects, please be careful not to overwrite with the same name as other custom styles

The difference between this and a custom style or media query is that the value is a pure string:

import React from "react";
import cssin, { addSheets } from "cssin";

addSheets({
  // Unlike custom styles, the value of a component is a string, which follows cSSIN syntax and can call other components and custom styles
  button: "bgc:#f66; hover:bgc:#f22; padding:8px; color:--button-color;"
});

// You only need to wrap the declaration around one word
export default() = > {return <div className={cssin`button; `} >Button</div>;
};
Copy the code

Note that components cannot be combined with pseudo-class or media queries because they already contain them inside the component

Cover the setAttribute

This involves some magic, please use dialectically.

Authors don’t want to reference CSSIN every time they write code. This is too cumbersome for authors. If you feel that way, you can use CSSIN’s coverAttribute

index.js

import React from "react";
import { coverAttribute } from "cssin";

// Here we override the inlist object, which simulates className={cssin '... `}
coverAttribute("inlist");

// Make sure coverAttribute is executed before reactdom.render
ReactDOM.render(<App />, document.getElementById("root"));
Copy the code

App.js

import React from "react";

// Eventually, a one-word declaration is required, just like a native declaration
export const App = (a)= > {
  return (
    <div inlist="full; m:20px;">
      <div inlist="button">Button</div>
    </div>
  );
};
Copy the code

Inlint can be used with classnames, provided that classnames must be declared before inlist

import React from "react";

// Eventually, a one-word declaration is required, just like a native declaration
export const App = (a)= > {
  return (
    <div>
      <div className="app-box" inlist="button">
        Button
      </div>
    </div>
  );
};
Copy the code

It is important to note that overwriting setAttribute is not the right approach because it can be very unfriendly to other developers who don’t know we are doing dark magic and are very confused.

Also, do not overwrite common attributes such as className, which invalidates other component libraries

Use CSS native functionality in javascript

use{}Write simple CSS fragments

Sometimes, we’ll need to write a simple CSS fragment. We’ll agree that if a string contains {}

The string passed in is then injected into HTML as a pure CSS style

import cssin from "cssin";

cssin` body { margin: 0px; background-color: #f5f5f5; } @media (min-width: 640px) { .box { background: #f00; }} `;
Copy the code

use.Reference native CSS

Native CSS defined elsewhere can be mixed with CSSin by adding. To the property name:

import React from "react";
import cssin from "cssin";

// Use.box to reference CSS styles
export default() = > {return <div inlist="margin:4px; .box">Button</div>;
};
Copy the code

Use default custom styles, components, CSS-values

Cssin provides a complete set of preset custom style collections and CSS-value collections, which are well designed, out of the box, and can also be used as a reference sample of a custom style collection

By default, cSSIN does not configure it, if we want to configure it as follows:

import "cssin/commonSheets"; // Introduce the sheets collection
import "cssin/commonCSSValues"; // Introduce the CSS-value collection
Copy the code

CommonSheets content:

Custom style name Mapping style use
dis display dis: flex;
items align-items items: 20px;
justify justify-content justify: start;
self align-self self: center;
content align-content content: end;
z z-index z: 10;
p padding p: 5rem;
px pading-left, padding-right px: 5rem;
py padding-top, padding-bottom py: 5rem;
pl padding-left pl: 5rem;
pt padding-top pt: 5rem;
pr padding-right pr: 5rem;
pb padding-bottom pb: 5rem;
m margin m: 5rem;
mx margin-left, margin-right mx: 5rem;
my margin-top, margin-bottom my: 5rem;
ml margin-left ml: 5rem;
mt margin-top mt: 5rem;
先生 margin-right mr: 5rem;
mb margin-bottom mb: 5rem;
w width w: 5rem;
w-min min-width w-min: 5rem;
w-max max-width w-max: 5rem;
w-min-max min-width, max-width w-min-max: 5rem;
h height h: 5rem;
h-min min-height h-min: 5rem;
h-max max-height h-max: 5rem;
h-min-max min-height, max-height h-min-max: 5rem;
b border: ${v} solid; b: 5rem;
bl border-left: ${v} solid; bl: 5rem;
bt border-top: ${v} solid; bt: 5rem;
br border-right: ${v} solid; br: 5rem;
bb border-bottom: ${v} solid; bb: 5rem;
bc border-color bc: #f00;
radius border-radius radius: 2rem;
font font-size The font: 1.25 rem;
bg background background: #f00;
bgc background-color bgc: #f00;
linear transition: all ${v} linear; Linear: 0.3 s;
ease transition: all ${v} ease; Ease: 0.3 s;
ease-in transition: all ${v} ease-in; Ease – in: 0.3 s;
ease-out transition: all ${v} ease-out; Ease – out: 0.3 s;
ease-in-out transition: all ${v} ease-in-out; Ease – in-out: 0.3 s;
move-x transform: translateX(${v}); move-x: 50%;
move-y transform: translateY(${v}); move-y: 50%;
move-z transform: translateZ(${v}); move-z: 50%;
rotate transform: rotate(${v}deg); rotate: 180;
scale transform: scale(${v}, ${v}); Scale: 0.7;
The following are components Components do not need to set values
col dis:flex; flex-direction:column; col;
row dis:flex; flex-direction:row; row;
center col; justify:center; items:center; center;
fixed position:fixed; fixed;
static position:static; static;
absolute position:absolute; absolute;
relative position:relative; relative;
sticky position:sticky; sticky;
left left:0px; left;
top top:0px; top;
right right:0px; right;
bottom bottom:0px; bottom;
bold font-weight: bold; bold;

CommonCSSValues sets some css-values, where the colors, sizes, and projections are taken from the configuration of tailwindCSS:

Using default examples:

import React from "react";
import cssin from "cssin";

// Use default custom styles in conjunction with CSS-value
export default() = > {return (
    <div
      className={cssin`
        bg:--gray-200; 
        p:--2; 
        font:--font-sm; 
        box-shadow:--shadow-xl
      `}
    >
      Button
    </div>
  );
};
Copy the code

We can check out these two files, which are simple configurations using the CSSIN API, and welcome friends to provide better custom styles and components:

commonSheets.ts

commonCSSValues.ts

Performance overhead

Cssin creates CSS styles at run time, but it has a very low performance overhead.

As we can see, creating 500 iterations of about 20 styles each took only 1.6ms, because CSSIN caches the overall attribute as well as the CSS styles created for sub-attributes:

console.time(t);
for (let i = 0; i < 500; i++) {
  cssin(
    ` transition: 0.1 s ease - in all; box-shadow:--shadow-1lg; hover:box-shadow:--shadow-1md; active:box-shadow:--shadow-sm1; `
  );
  cssin(
    ` transition: 0.2 s ease - in all; box-shadow:--shadow-2lg; hover:box-shadow:--shadow-2md; active:box-shadow:--shadow-sm2; `
  );
  cssin(
    ` transition: 0.3 s ease - in all; box-shadow:--shadow-3lg; hover:box-shadow:--shadow-3md; active:box-shadow:--shadow-sm3; `
  );
  cssin(
    ` transition: 0.4 s ease - in all; box-shadow:--shadow-4lg; hover:box-shadow:--shadow-4md; active:box-shadow:--shadow-sm4; `
  );
}
console.timeEnd(t); / / 1.60009765625 ms
Copy the code

Start using it now:

$ npm i cssin --save
Copy the code

Looking for Star or contributions, warehouse address:

Github.com/ymzuiku/css…