- Making divs user resizable with CSS
- CSS resize property permalink
- CSS Removing resize attribute permalink
- Thank you for reading, and let’s connect! permalink
- clubmate.fi
- How to resize HTML elements: with few lines of CSS, using a React hook, or with pure JavaScript
- resize
- Try it
- Syntax
- Values
- Formal definition
- Formal syntax
Making divs user resizable with CSS
This article has nothing to do with browser widths and viewport media queries.
In this article, we will be talking about the resize css property.
This is one property I only came across recently, because when do you actually need the user to resize something other than a textarea box.
In my article demonstrating how the HTML tag works, I used the resize property to showcase when the words would break.
You might find yourself in need of this one-day, so here we go, an example of how the CSS resize property works and what options it has.
The end result will look like the following GIF.
CSS resize property permalink
To add the option we can use the following syntax:
- none : Default, user cannot resize the element
- both : Resize horizontal and vertical
- horizontal : Only resize horizontally
- vertical : Only resize vertically
- initial : Reset back to the initial value
- inherit : Inherit value from the parent element
To make them effective, let’s create some examples:
What’s really important to know is that by default, the resize code will not do anything.
This is because the default overflow value is visible, and that will disable the resize.
We can use any of these overflow values: scroll , auto , hidden .
First let’s define a basic box to start with:
div width: 100px; height: 100px; overflow: auto; >
Now let’s make a pink box that can resize both ways:
div.both resize: both; background: #ef476f; >
Perhaps we only want a horizontal resize? Check out the yellow box.
div.horizontal resize: horizontal; background: #ffd166; >
Over even just vertical, check out the green box
div.vertical resize: vertical; background: #06d6a0; >
You can see these boxes in action on the following Codepen.
CSS Removing resize attribute permalink
There is one case where perhaps you want to remove the resize attribute, and this is with textareas.
They come with a default resize property, and we can turn this off by using the following code:
You can try this out on the following Codepen.
Thank you for reading, and let’s connect! permalink
Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter
clubmate.fi
How to resize HTML elements: with few lines of CSS, using a React hook, or with pure JavaScript
How to resize DOM elements supers easily with pure CSS, or in a more fancy way using React lib.
You know how textareas can be resized easily by dragging from the corner? This same behavior can be activated for any type of element.
For example, the below demo is showing the classic Holy Grail layout. When rendering it, I think it’s important to see the fluidity of the layout, which makes a good use-case for resizable content:
Choose the resizing behavior:
Test in FireFox for full effect Sidebar content Holy Grail
Here’s how that component looks like (nothing too surprising there):
const HolyGrail = () => ( Wrap> Header>Resizable wrapperHeader> SidebarLeft>Sidebar contentSidebarLeft> Content> p>Choose the resizing behavior:p> Content> SidebarRight>Sidebar contentSidebarRight> Footer>Holy GrailFooter> Wrap> )
When using it, wrap it to a ResizableContainer component to make it resizable:
ResizableContainer> HolyGrail /> ResizableContainer>
That’s pretty simple, check the CSS below.
Here’s the CSS for the resizable container:
.resizable-container height: 400px; overflow: auto; resize: both; >
The height is not necessarily needed, I just like it since it’s a wrapper, then I blast the inner component 100% height. The overflow should be anything else than visible .
Possible values for resize are:
none The resizing is just basically deactivated. both Both axis, Y and X, are subjected to resizing. horizontal Size can only be changed horizontally (X axis ↔︎). vertical Only vertical sizing is possible (Y axis ↕︎). block experimental The element displays a mechanism for allowing the user to resize it in the block direction (either horizontally or vertically, depending on the writing-mode and direction value). inline experimental The element displays a mechanism for allowing the user to resize it in the inline direction (either horizontally or vertically, depending on the writing-mode and direction value).
About the block and inline values
If I understand right, the block and inline values are just a different ways of saying horizontal and vertical, because some languages (like Japanese) are written from top to bottom. If my computer would be in Japanese, setting resize to block would actually be same as horizontal, where as in my English computer it means vertical.
Disabling textarea resizing
By setting resize: none you can easily disable textarea sizing:
Which I think is the only HTML element that has resizing on by default.
Browser support for resize
This is an old feature, I’ve just learned about it recently heh. The block and inline modes only work in FireFox for now (2021).
Iframes can be made resizable the same as any other element, comes handy when displaying demos and such.
I wrapped the Iframe to a div , and set the resizing to the outer element, then set the Iframe width and height to 100%:
div style="resize: both; overflow: auto; height: 300px;"> iframe src="https://clubmate.fi" style="width: 100%; height: 100%; border: 1px solid #aaa" >iframe> div>
Resizable React component
The only benefit of making something resizable with JavaScript: have more control.
Below is a component made using a simple resize hook I wrote. Compared to the CSS implementation it has few advantages:
- It gives you the size of the box.
- You can define a sizing step, in the pink example below it’s 40px.
- The look of the handle can be controlled. I’m using a CSS triangle.
- The transition between the steps can be animated.
There’s 3 parts to the code that renders that box.
I build it as a render prop component, so the size is returned from the function. The usage of it looks like this:
ResizableComponent options= step: 40 >>> size => ( span> I’m resizable, my size is size.width> x size.height> span> )> ResizableComponent>
At the heart of it, is the useResize hook (below), which doesn’t render anything on its own, but merely provides the logic. You feed the hook a ref to the element you want to resize, and the optional options. Building a hook, rather than a component makes it super flexible, you’re not bound to the limitations of the component, but can make your own.
The resizing hook gives back 3 things: initResize , size , and cursor (more on those below):
import React from 'react' import PropTypes from 'prop-types' import useResize > from './useResize' import Handle, Resizable > from './styles' const ResizableComponent = props => const ref = React.useRef() const initResize, size, cursor > = useResize(ref, props.options) return ( Resizable ref=ref>> props.children(size)> Handle cursor=cursor> onMouseDown=initResize> /> Resizable> ) >
This hooks is pretty basic, you could easily bake in more features to it if needed, like keyboard support, Max/min dimensions and so on. But there’s already many React helpers for resizing components, building this hook was more of an exercise.
See a demo in CodeSandbox:
ref A ref to the resized component. Use React.useRef() options.step A px value, i.e.: 40. The box will be resized with this interval. options.axis both|horizontal|vertical . Both is the default.
An the resize hook will return these three things:
initResize A function, which you should call with an onMouseDown in your resizing handle. size This is the live size of the resized box. cursor This depends on the sizing axis passed in options.axis . Then you can pass this along into the your resizing handle.
import React from 'react' const cursor = both: 'nwse-resize', vertical: 'ns-resize', horizontal: 'ew-resize' > export const useResize = (ref, options) => ref = ref || > const step = 1, axis = 'both' > = options || > const [coords, setCoords] = React.useState( x: Infinity, y: Infinity >) const [dims, setDims] = React.useState( width: Infinity, height: Infinity >) const [size, setSize] = React.useState( width: Infinity, height: Infinity >) const initResize = event => if (!ref.current) return setCoords( x: event.clientX, y: event.clientY >) const width, height > = window.getComputedStyle(ref.current) setDims( width: parseInt(width, 10), height: parseInt(height, 10) >) > React.useEffect(() => // Round the size based to `props.step`. const getValue = input => Math.ceil(input / step) * step const doDrag = event => if (!ref.current) return // Calculate the box size. const width = getValue(dims.width + event.clientX - coords.x) const height = getValue(dims.height + event.clientY - coords.y) // Set the box size. if (axis === 'both') ref.current.style.width = width + 'px' ref.current.style.height = height + 'px' > if (axis === 'horizontal') ref.current.style.width = width + 'px' if (axis === 'vertical') ref.current.style.height = width + 'px' setSize( width, height >) > const stopDrag = () => document.removeEventListener('mousemove', doDrag, false) document.removeEventListener('mouseup', stopDrag, false) > document.addEventListener('mousemove', doDrag, false) document.addEventListener('mouseup', stopDrag, false) >, [dims, coords, step, ref, axis]) return initResize, size, cursor: cursor[axis] > >
Make element resizable with vanilla JavaScript
div id="box" class="box">Click the element to make it resizable.div>
const el = document.getElementById('box') el.addEventListener('click', init, false) const coords = x: Infinity, y: Infinity > let startWidth, startHeight function init() el.removeEventListener('click', init, false) el.classList.add('resizable') makeTheHandle() > function makeTheHandle() const handle = document.createElement('div') handle.classList.add('handle') el.appendChild(handle) handle.addEventListener('mousedown', initDrag, false) > function initDrag(event) coords.x = event.clientX coords.y = event.clientY startWidth = parseInt(window.getComputedStyle(el).width, 10) startHeight = parseInt(window.getComputedStyle(el).height, 10) document.addEventListener('mousemove', doDrag, false) document.addEventListener('mouseup', stopDrag, false) > function doDrag(event) el.style.width = startWidth + event.clientX - coords.x + 'px' el.style.height = startHeight + event.clientY - coords.y + 'px' > function stopDrag() document.removeEventListener('mousemove', doDrag, false) document.removeEventListener('mouseup', stopDrag, false) >
.box background-color: Pink; padding: 20px; position: relative; > .handle background-color: Black; bottom: 0; cursor: se-resize; height: 10px; position: absolute; right: 0; width: 10px; >
I would use the native CSS solution whenever possible, and then fallback to a JS solution if I have design or accessibility needs that are not met by the native resize .
There are also resizing sensors out there, that detect resizing and return the dimensions etc. Here’s just few first ones I found with a quick search:
Thanks for reading. Hope this was helpful.
resize
The resize CSS property sets whether an element is resizable, and if so, in which directions.
Try it
resize does not apply to the following:
Syntax
/* Keyword values */ resize: none; resize: both; resize: horizontal; resize: vertical; resize: block; resize: inline; /* Global values */ resize: inherit; resize: initial; resize: revert; resize: revert-layer; resize: unset;
The resize property is specified as a single keyword value from the list below.
Values
The element offers no user-controllable method for resizing it.
The element displays a mechanism for allowing the user to resize it, which may be resized both horizontally and vertically.
The element displays a mechanism for allowing the user to resize it in the horizontal direction.
The element displays a mechanism for allowing the user to resize it in the vertical direction.
The element displays a mechanism for allowing the user to resize it in the block direction (either horizontally or vertically, depending on the writing-mode and direction value).
The element displays a mechanism for allowing the user to resize it in the inline direction (either horizontally or vertically, depending on the writing-mode and direction value).
Formal definition
Initial value | none |
---|---|
Applies to | elements with overflow other than visible , and optionally replaced elements representing images or videos, and iframes |
Inherited | no |
Computed value | as specified |
Animation type | discrete |
Formal syntax
resize =
none |
both |
horizontal |
vertical |
block |
inline