2.0.0 • Published 4 years ago

@curiousmedia/contain v2.0.0

Weekly downloads
3
License
MIT
Repository
-
Last release
4 years ago

Contain

Scale child element to fit into parent. Common use case would be a full screen modal containing a video.

Basic usage

CSS

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  box-sizing: border-box;
}

*,
*::before,
*::after {
  box-sizing: inherit;
}

.parent {
  overflow: hidden;
  width: 100%;
  height: 100%;
  position: relative;
}

.child {
  background-color: #CCC;
}

HTML

<div class="parent">
    <div class="child"></div>
</div>

Javascript

import Contain from "@curiousmedia/contain";
let parent = document.querySelector('.parent');
let child = document.querySelector('.child');

window.addEventListener('resize', resize);
function resize() {
    let size = Contain.size(
        1.7778, // 16:9
        1.3333, // 4:3
        'contain', //Resize method
        parent //Pass parent element
    );
    
    Contain.resizeElement(child, size);
}

Documentation

Contain.size(minAspectRatio, maxAspectRatio, method, availableWidth, availableHeight)

  • minAspectRatio {Number} Minimum aspect ratio of child element. Set to 0 allow all aspect ratios.
  • maxAspectRatio {Number} Maximum aspect ratio of child element. Set to value of minRatio to lock a single aspect ratio.
  • mode {String|Function} Resize mode.
    • contain Child will fit within parent at maximum allowed aspect ratio. Matches background-size: contain CSS style.
    • cover Child will fill parent at maximum allowed aspect ratio. Matches background-size: cover CSS style.
    • width Child width will fill parent. Height will attempt to fill parent within allowed aspect ratios.
    • height Child height will fill parent. Width will attempt to fill parent within allowed aspect ratios.
    • Custom resize callback can be defined. Attempts parameters availableWidth, availableHeight, and aspectRatio. Expected to return an array with width and height.
  • availableWidth {number|Element} Available width for child element. Defaults to window.innerWidth. Also accepts Element; see below for details.
  • availableHeight {number} Available height for child element. Defaults to window.innerHeight. Ignored if Element is passed to availableWidth.

Returns an array containing width and height.

Contain.resizeElement(element, size)

Helper function to apply size to an element.

  • element {Element} HTML element to resize
  • size {number[]} Array containing width and height

constructor(minAspectRatio, maxAspectRatio, mode, element)

Contain can be used as a class instance. Instead of availableWidth and availableHeight, an HTML element is passed as the fourth parameter.

resize(useCacheStyle)

Returns calculated width and height from class instance.

  • useCacheStyle {boolean} Cache style of parent element used to calculate availableWidth and availableHeight. Defaults to false.

Calculating available size

If and Element is passed as the availableWidth parameter in Contain.size() or Contain is implemented as an instance, availableWidth and availableHeight will my automatically caculated. The calculation will take the dimension and subtract relevant padding and border width. For this reason, it is highly recommended to have parent and child elements box-sizing CSS property set to border-box for proper calculation.

Resize optimization

When using Contain on resize, Lodash Debounce is highly recommended to avoid superfulous calculations and increase performance.

Examples

Fill parent at any aspect ratio

let size = Contain.size(0, 0, 'contain', document.querySelector('.parent'));

Contain.resizeElement(document.querySelector('.child'), size);

Fit child into parent at single aspect ratio

let size = Contain.size(16/9, 16/9, 'contain', document.querySelector('.parent'));

Contain.resizeElement(document.querySelector('.child'), size);

Fit child between allowed aspect ratios

The contain mode will behave similar to the background-size: contain CSS style.

let size = Contain.size(16/9, 4/3, 'contain', document.querySelector('.parent'));

Contain.resizeElement(document.querySelector('.child'), size);

Fill parent between allowed aspect ratios

The cover mode will behave similar to the background-size: cover CSS style.

let size = Contain.size(16/9, 4/3, 'cover', document.querySelector('.parent'));

Contain.resizeElement(document.querySelector('.child'), size);

Fill parent width and fit height within aspect ratios

let size = Contain.size(16/9, 4/3, 'width', document.querySelector('.parent'));

Contain.resizeElement(document.querySelector('.child'), size);

Fill parent height and fit width within aspect ratios

let size = Contain.size(16/9, 4/3, 'height', document.querySelector('.parent'));

Contain.resizeElement(document.querySelector('.child'), size);

Custom mode

let size = Contain.size(16/9, 4/3, function(availableWidth, availableHeight, aspectRatio) {
    return [availableWidth / 2, availableHeight / 2]
  }, document.querySelector('.parent'));

Contain.resizeElement(document.querySelector('.child'), size);

Set parent size manually

let size = Contain.size(16/9, 4/3, 'contain', 400, 400);

Contain.resizeElement(document.querySelector('.child'), size);

Implementation as instance

let c = new Contain(
    16/9,
    4/3,
    'contain',
    document.querySelector('.parent')
  );

Contain.resizeElement(document.querySelector('.child'), c.resize());