CSS-Only Resizable Elements

In Playing With (Fake) Container Queries Chris used the <resize-asaurus> web component to make the elements resizable. Curious to see how that worked I dug into its source.

As I was expecting a truckload of JavaScript to make it work, I was very surprised to see that it basically revolved around using just one single CSS property: resize

The resize CSS property sets whether an element is resizable, and if so, in which directions.

Accepted values for resize are none, horizontal, vertical, and both.

To play nice with CSS Logical Properties the values block and inline will also be supported.

😅 Up until then I thought resize was a thing reserved for <textarea> only.

~

Demo

To get resize working, one must apply it on a block level element + also set overflow to any value but visible. Below is a demo with resize set to both:

See the Pen
Resizable Element (Pure CSS)
by Bramus (@bramus)
on CodePen.

Don’t forget to set min-width/min-height/max-width/max-height in case you want to prevent the resizable box from becoming too small/big.

~

Resizing iframe elements

A very practical use-case for this is resizable iframe elements: As many embedded CodePen pens are responsive, you want your visitor to be able to resize them.

🙃 As by coincidence, Ahmad asked for exactly this on Twitter just yesterday:

Could this be a task for CSS resize property you ask? Why yes, but there’s one big problem though: resize and <iframe> don’t play nice together as an <iframe> is a replaced element.

🙋‍♂️ Replaced Elements?

As per spec:

A replaced element is an element whose content is outside the scope of the CSS formatting model, such as an image or embedded document. For example, the content of the HTML img element is often replaced by the image that its src attribute designates.

iframe, canvas, iframe, etc. also are Replaced Elements.

Of course, as with many web things, there’s a little workaround we can use:

  1. Wrap the <iframe> in a <div>, and make the <div> resizable.
  2. Have <iframe> strech along with the <div>‘s dimensions, using Flexbox.

Like so:

See the Pen
Resizable iframe (Pure CSS)
by Bramus (@bramus)
on CodePen.

As images also are replaced elements (see above), you need to apply a similar trick to be able to resize them:

See the Pen
Resizable image (Pure CSS)
by Bramus (@bramus)
on CodePen.

☝️ Note that I also added an object-fit rule in there, to prevent aspect ratio distortion.

~

Browser Support

Resize is supported in all major browsers, except for MobileSafari (e.g. Safari on iOS). A shame though, as this once again pushes MobileSafari into the “(Mobile)Safari is the new IE6” corner …

Data on support for the css-resize feature across the major browsers from caniuse.com

💡 Shown above is a dynamic CanIUse.com image, showing an always up-to-date support table. By the time you are reading this browser support might have become better.

Sidenote: @supports vs. resize: both; vs. MobileSafari

In the demo above I wanted to show a warning in browsers that don’t support resize: both;. For that I tried using @supports, which has proven to be successful before.

.warning {
	display: block;
}

/* Hide warning in case browser supports resize: both; */
@supports (resize: both) {
    .warning {
        display: none;
    }
}

MobileSafari however also hides the warning and thus falsely claims to support resize: both.

I’ve reported a bug on this: https://bugs.webkit.org/show_bug.cgi?id=211994

~

Did this help you out? Like what you see?
Thank me with a coffee.

I don't do this for profit but a small one-time donation would surely put a smile on my face. Thanks!

☕️ Buy me a Coffee (€3)

To stay in the loop you can follow @bramus or follow @bramusblog on Twitter.

ResizeObserver now available in Chrome

Chrome 64 includes ResizeObserver:

ResizeObserver notifies you whenever an element’s size changes, and provides the new height and width of the element, reducing the risk of layout thrashing.

To use it create a new instance of it, and then make it observe one or more elements:

var ro = new ResizeObserver(entries => {
  for (let entry of entries) {
    const cr = entry.contentRect;
    console.log('Element:', entry.target);
    console.log(`Element size: ${cr.width}px x ${cr.height}px`);
    console.log(`Element padding: ${cr.top}px ; ${cr.left}px`);
  }
});

// Observe one or multiple elements
ro.observe(someElement);

New in Chrome 64: ResizeObserver
ResizeObserver: It’s Like document.onresize for Elements →

NYSKeyboardHelper – A helper for all your iOS keyboard needs

Matthias Nys, a former student of mine, has released his first pod NYSKeyboardHelper, a helper which resizes a scrollview so that it doesn’t go under the keyboard.

Add a constraint to your project’s Storyboard and set NYSKeyboardHelper as the custom class, or add it programmatically:

let keyboardConstraint = NYSKeyboardHelper(item: self.view, attribute: .bottom, relatedBy: .equal, toItem: scrollView, attribute: .bottom, multiplier: 1.0, constant: 0.0)
keyboardConstraint.extraIndent = 10.0
self.view.addConstraint(keyboardConstraint)

NYSKeyboardHelper – A Helper for all your keyboard needs →

In React Native, use the KeyboardAvoidingView to make sure the keyboard doesn’t overlap with the content 😉