npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@phntms/layout

v0.0.1

Published

A lightweight library to implement fully responsive REM based layouts.

Downloads

7

Readme

layout

NPM version Actions Status PR Welcome

A lightweight library to implement fully responsive REM based layouts in CSS-in-JS based libraries. Also SSR safe and won't break build if pre-rendered.

Installation

Install this package with npm.

npm i @phntms/layout

Usage

Initialize a new Layout() instance. On creation, you can also define custom configs or leave blank to inherit the default config.

To use, we recommend creating a global singleton file, this allows you to reference the layout anywhere in the project. Example singleton:

import Layout from "@phntms/layout";

export default new Layout();

// Or...

export default new Layout<"mobile" | "tablet" | "desktop">({
  mobile: {
    breakpoint: 768,
    targetViewportWidth: 375,

    // Number of columns to show below 767
    columns: 16,
  },

  tablet: {
    breakpoint: 1032,
    targetViewportWidth: 1032,

    // Number of columns to show between 768 and 1031
    columns: 20,
  },

  desktop: {
    breakpoint: 1440,
    targetViewportWidth: 1440,

    // Number of columns to show above 1032
    columns: 24,
  },
});

Note: If you want to have full control over your config and prefer not to use any defaults provided, you can set applyDefaultConfig to false.

import Layout from '@phntms/layout';

export default new Layout({...}, false);

Then to use, simply import the newly created layout singleton file. For example:

import layout from "~/layout";

initialize()

To apply the config set in the constructor and once the app has loaded, this method is required to initialize the layout. Example usage:

import layout from "~/layout";

layout.initialize();

destroy()

Optional method used to unsubscribe from event listeners at end of lifecycle. Example usage:

import layout from "~/layout";

layout.destroy();

pxToRem()

Used to convert PX values to REM. Example usage:

import layout from "~/layout";

layout.pxToRem(10, false, "desktop");

In this example, we're converting 10px to rem at the targetScreenSize of desktop.

But, what does that mean?

Each breakpoint has a targetScreenSize. This is the size that we're basing our fluid rem values on. So in the example above, the default target is 1440, which means at a screen size of 1440px, the value will visually be 10px (0.167rem in rem).

Other examples based on the default config:

  • Mobile: pxToRem(5, false, 'mobile') = Visually 5px at 375px.
  • Tablet: pxToRem(5, false, 'tablet') = Visually 5px at 1024px.
  • Desktop: pxToRem(5, false, 'desktop') = Visually 5px at 1440px.

What about if the screen size is higher?

The value will simply scale visually beyond 10px, though the actual rem value won't change.

What about if the screen size is lower?

Theres three different possible outcomes here.

In the example above as pxAsMin is set to false, the value would visually scale below 10px until we reached a screen size of 0px or until we reach a new breakpoint.

If pxAsMin was set to true, that value would stop visually scaling once the screen reaches 1440px in width.

Alternatively, if pxAsMin is set to an integer value, such as 8px, the value would visually scale till it reaches 8px in size or a new breakpoint is reached.

In all outcomes the value will be visually unaffected if scaling above the base value.

Note: CSS max is used under the hood to clamp values, which means -${pxToRem(10, true, ...)} wouldn't work if this is enabled as the result - -max(10px, 0.167rem) would be invalid. To use negative values, define them inside as the px value. Or set this to false, at which point -${pxToRem(10, false, ...)} is valid as it would result in -0.167rem.

columns()

Used to create grid columns, irrespective of the current breakpoint.

import layout from "~/layout";

layout.columns(1);

This library works by dividing the screen into a number of columns, for example 24 by default on desktop. The nice part of this is that 1 gutter (on mobile, tablet, desktop or any breakpoint) = 1 rem.

Note: We recommend only using columns for horizontal spacings, where vertical spacings should use pxToRem based values.

toggleColumnOverlay()

Optional method used to toggle if column overlay is showing or not.

import layout from "~/layout";

layout.toggleColumnOverlay();

Note: To use grid overlay, you need to additionally import overlay.css. For example:

import "@phntms/layout/src/overlay.css";

🍪 Example Usage

The following examples are all in styled-components, though they would work in any other CSS-in-JS based libraries.

Media Queries

Due to how different browsers calculate media queries, when using rem based libraries such as this one, its recommended to use em values over px and rem. For further reading, see this article exploring the topic. With this in mind, following is an example of how you might want to layout global queries:

const pxToEm = (px: number) => px / 16;

export const BREAKPOINT_MOBILE = DEFAULT_CONFIG.mobile.breakpoint;
const BREAKPOINT_MOBILE_AS_EM = `${pxToEm(BREAKPOINT_MOBILE)}em`;
/** 768px. */
export const QUERY_GREATER_THAN_MOBILE = `(min-width: ${BREAKPOINT_MOBILE_AS_EM})`;

export const BREAKPOINT_TABLET = DEFAULT_CONFIG.tablet.breakpoint;
const BREAKPOINT_TABLET_AS_EM = `${pxToEm(BREAKPOINT_TABLET)}em`;
/** 1032px. */
export const QUERY_GREATER_THAN_TABLET = `(min-width: ${BREAKPOINT_TABLET_AS_EM})`;

export const BREAKPOINT_DESKTOP = DEFAULT_CONFIG.desktop.breakpoint;
const BREAKPOINT_DESKTOP_AS_EM = `${pxToEm(BREAKPOINT_DESKTOP)}em`;
/** 1440px. */
export const QUERY_GREATER_THAN_DESKTOP = `(min-width: ${BREAKPOINT_DESKTOP_AS_EM})`;

Scaling Typography

Combining the media queries above with type or any other value (such as paddings / margins etc), means you can then create values that scale fully based on the current breakpoint, for example:

import { css } from "styled-components";

import layout from "~/layout";

export const TYPE_SIZE_LARGE = css`
  font-size: ${layout.pxToRem(17, 14, "mobile")};

  @media ${QUERY_GREATER_THAN_MOBILE} {
    font-size: ${layout.pxToRem(17, 14, "tablet")};
  }

  @media ${QUERY_GREATER_THAN_TABLET} {
    font-size: ${layout.pxToRem(17, 14, "desktop")};
  }
`;

In this example, type will always maintain its base 17px font size at the targetViewportWidth of each breakpoint. Though if type has a small base value, we recommend always adding a minimum font size for type legibility to ensure it never becomes too small. Here we set a minimum of 14px.

Grid

Here is an example of using the columns to create a fully fluid grid!

import styled from 'styled-components';

import layout from '~/layout';

const Cards = styled.div`
  display: grid;
  grid-column-gap: ${layout.columns(1)};
  grid-template-columns: repeat(3, ${layout.columns(6)});

  // Can even be used alongside `pxToRem`!
  margin-bottom: ${layout.pxToRem(60, true, 'desktop')}
`;

🍰 Contributing

Want to get involved, or found an issue? Please contribute using the GitHub Flow. Create a branch, add commits, and open a Pull Request or submit a new issue.

Please read CONTRIBUTING for details on our CODE_OF_CONDUCT, and the process for submitting pull requests to us!