adaptive-pixel
v1.0.1
Published
Creating fully flexible / responsive web interfaces. Provides a multiplier value for interface scaling via CSS and JS.
Downloads
124
Maintainers
Readme
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
- You can set breakpoints for different scaling on different screen resolutions (depending on your mockups).
- The script will calculate the screen scaling multiplier value and add/remove listeners to recalculate on window 'resize' and 'orientationchange' events.
- This multiplier value will be stored/updated in CSS variable
--apx
in :root of documetn. And also sent as a numder to callback. - In SASS you can use it with helpful mixins that convert incoming values to CSS syntax
calc(var(--apx, 1px) * #{$your_value})
. - 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
.
- 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. - 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). - 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. |
Add CSS variables to the :root
| name | value |
| --------- | ------------ |
| --apx
| ${value}px
|
| --scale
| ${value}
|
📜 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
| zero0
=> line-height: normal
number non zero18
=> line-height: apx(18)
number + %130%
=> line-height: 130%
nullnull
=> 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)
📜 +altrb($l, $t, $r, $b, $w, $h)
Return next:
position: absolute
margin: auto
+alt($l, $t)
+arb($r, $b)
+awh($w, $h)
📜 +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.
JS Helpers
apxCssValue (val: number) => string
Get a number and return a string for inline css style: calc(var(--apx, 1px) * ${val})
(like a SASS mixin apx()
).
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