adaptive-pixel
TypeScript icon, indicating that this package has built-in type declarations

1.0.0 • Public • Published

adaptive-pixel

This is a package for creating fully flexible / responsive web interfaces.

Provides a multiplier value for interface scaling via CSS and JS. Based on customizable media breakpoints.

Also contains SASS mixins for ease of use.

How it works

  1. You can set breakpoints for different scaling on different screen resolutions (depending on your mockups).
  2. The script will calculate the screen scaling multiplier value and add/remove listeners to recalculate on window 'resize' and 'orientationchange' events.
  3. This multiplier value will be stored/updated in CSS variable --apx in :root of documetn. And also sent as a numder to callback.
  4. In SASS you can use it with helpful mixins that convert incoming values to CSS syntax calc(var(--apx, 1px) * #{$your_value}).
  5. If you set breakpoints according to your mockups, you can take all sizes as is from there for use in mixins. In this case, mockup content will be scaled in the viewport with contain strategy.
    (see more below)

Demo

React + SASS live demo and code.

Installation

npm i adaptive-pixel

Usage JS

📜 getApxInterface

Function retun an interface that can calculates a multiplier value for scaling, and can add/remove listeneres for refresh value on window 'resize' and 'orientationchange' events.

After calculation (and if this is a new value) puts it to CSS variable --apx to the :root of document, and also sends a new value to the callback function.

import { getApxInterface } from "adaptive-pixel";

const params = {
  setter: (value: number) => console.log("apx", value),
  breakpoints: [[...], [...], ...],
};

const { calculate, startListeners, cleanListeners } = getApxInterface(params);

params

Property Describe
setter (optional) | (value: number) => void
Callback that fires when a new apx value is calculated. Recive a new value as a number.
breakpoints (optional) | [number, number, number?, number?][]
Array of breakepionts.
Default: see below.

All breakepoints listed in descending order of priority. Each breakpoint contains [mockup width, mockup height, screen min-width, screen min-height].
Default values, for example:

[
  [1440, 750, 900, 540], // "Desktop"
  [360, 1, 300, 300], // "Mobile"
];

In this case we have two mockup resolutions: "Desktop" 1440 x 750 and "Mobile" 360 x any.

  1. First we check that the screen (min-width: 900px) and (min-height: 540px). If it's true, "Desktop" content will scale on screen with contain strategy. If not — go to the next breakpoint.
  2. Now we check that the screen (min-width: 300px) and (min-height: 300px). If it's true, "Mobile" content will scale on screen with contain strategy (and mockup height = 1 means that screen height does not need to be taken into account).
  3. If there are no more breakpoints in the list, then set scale multiplier to 1 (no scaling at all).

Instance methods

Method Describe
calculate() Run calculation.
startListeners() Add listeners to window 'resize' and 'orientationchange' events for recalculation.
cleanListeners() Remove listeners.

📜 getIsMobileInterface

Function retun an interface that can return match media check result (see below), and can add/remove listeneres for refresh value on match media update.

After match media checking or updating sends a new value to the callback function.

import { getIsMobileInterface } from "adaptive-pixel";

const params = {
  setter: (value: boolean) => console.log("isMobile", value),
  maxWidth: 900,
  maxHeight: 540,
};

const { calculate, startListeners, cleanListeners } =
  getIsMobileInterface(params);

params

Property Describe
setter (required) (value: boolean) => void
Callback that fires when a new "is mobile" state value is calculated. Recive a new value as a boolean.
maxWidth (optional) number
Default: 900
maxHeight (optional) number
Default: 540

setter recive true when match media is (max-width: ${maxWidth}px), (max-height: ${maxHeight}px) (viewport width < maxWidth OR height < maxHeight).

Note: Deafult maxWidth and maxHeight of getIsMobileInterface works great with default breakpoints of getApxInterface. If you set your own breakpoints, update those too.

Instance methods

Method Describe
calculate() Run calculation.
startListeners() Add window.matchMedia event listener for recalculation.
cleanListeners() Remove listeners.

Usage SASS

This package contains SASS mixins and functions to work with adaptive-pixel.

To use them in a .sass file, place it at the top:

@use 'adaptive-pixel/dist/mixins' as *

Functions

📜 apx($value [$value2 [...]])

Arguments: number [number [...]]

Converts one or more values to calc(var(--apx, 1px) * #{$value}) each. Zero will remain 0.

.block
  padding: apx(20 0 12)

// output
.block
  padding: calc(var(--apx, 1px) * 20) 0 calc(var(--apx, 1px) * 12)

Mixins

📜 +afs($size [, $height [, $weight]])

Arguments: number [, (number | number% | null) [, (number | string)]]

+afs() will return font-size, and if values are given line-height and font-weight CSS properties.

Argument Output examples
$size
number
16 => font-size: apx(16)
$height
(optional)
number | number% | null
zero
0 => line-height: normal

number non zero
18 => line-height: apx(18)

number + %
130% => line-height: 130%

null
null => no line-height output
$weight
(optional)
number | string
700 => font-weight: 700
bold => font-weight: bold
.text
  +afs(20, 130%, 700)

// output
.text
  font-size: apx(20)
  line-height: 130%
  font-weight: 700

📜 +awh($width [, $height])

📜 +alt($left [, $top])

📜 +art($right [, $top])

📜 +arb($right [, $bottom])

📜 +alb($left [, $bottom])

Arguments: number [, number]]

+awh() will return width and height CSS properties.
If $height is not provided, $width will be used for the height (eg: +awh(100) is equal to +awh(100, 100)).

Same for other mixins, but for the left, top, right and bottom respectively.

.block
  +awh(100)

// output
.block
  width: apx(100)
  height: apx(100)

📜 +desktop

📜 +mobile

This mixins will wrap CSS properties of the selector into the @media rules.

Mixin Media rule
+desktop (min-width: 901px) and (min-height: 541px)
+mobile (max-width: 900px), (max-height: 540px)
.block
  background: #FFF
  +desktop
    +awh(100, 200)
  +mobile
    +awh(60)

// output
.block
  background: #FFF

@media (min-width: 901px) and (min-height: 541px)
  .block
    width: calc(var(--apx, 1px)* 100)
    height: calc(var(--apx, 1px)* 200)

@media (max-width: 900px), (max-height: 540px)
  .block
    width: calc(var(--apx, 1px)* 60)
    height: calc(var(--apx, 1px)* 60)

Note: If you set your own breakpoints, you should make your own media mixins.

Examples

Below are examples for the getApxInterface, but the same for the getIsMobileInterface.

TS

import { getApxInterface } from "adaptive-pixel";

// will be called when the value is updated
const yourSetterCallback = (value: number) => console.log("apx", value);

const { calculate, startListeners, cleanListeners } = getApxInterface({
  setter: yourSetterCallback,
});

calculate(); // first run (on load, eg)
startListeners();

cleanListeners(); // remove listeners for cleanup if necessary

React

import { getApxInterface } from "adaptive-pixel";

export const SomeRootComponent: React.FC = () => {
  const [apx, setApx] = useState(1);

  useEffect(() => {
    const { calculate, startListeners, cleanListeners } = getApxInterface({
      setter: setApx,
    });

    calculate();
    startListeners();

    return () => {
      cleanListeners();
    };
  }, []);

  useEffect(() => console.log("apx", apx), [apx]);
  // ...
};

Svelte

// $lib/store/adaptivePixel.ts
import { writable } from "svelte/store";
import { getApxInterface } from "adaptive-pixel";

const createApxStore = () => {
  const { subscribe, set } = writable(1);
  const { calculate, startListeners, cleanListeners } = getApxInterface({
    setter: set,
  });

  return { subscribe, calculate, startListeners, cleanListeners };
};

const adaptivePixel = createApxStore();
export default adaptivePixel;
// +layout.svelte
import adaptivePixel from "$lib/store/adaptivePixel";

onMount(() => {
  adaptivePixel.calculate();
  adaptivePixel.startListeners();

  return () => {
    adaptivePixel.cleanListeners();
  };
});

$: console.log("adaptivePixel", $adaptivePixel);

SASS

@use 'adaptive-pixel/dist/mixins' as *

.block
  +awh(100, 200)
  padding: apx(40 20 30)

  +desktop
    +alt(20)
  +mobile
    +arb(16, 24)

.text
  +afs(20, 130%, 700)

  +desktop
    color: #C00
  +mobile
    color: #0C0

License

MIT

Package Sidebar

Install

npm i adaptive-pixel

Weekly Downloads

9

Version

1.0.0

License

MIT

Unpacked Size

38.9 kB

Total Files

10

Last publish

Collaborators

  • evgeniusly