Julian
Julian

Reputation: 1297

How to reduce, using CSS, a div's width once its max-height has been reached?

I'm trying to create a menu that can contain an undefined amount of objects; said objects' sizes are dependent on the available width (the width of the menu). The menu's height should never exceed certain value and still contain all the child objects, meaning that the child elements can shrink, while maintaining proportions, but never overflow the "containment area".

Something like this:

add = () => {
	const menuObject = document.createElement('div')
	menuObject.classList.add('menu-element')
	const menu = document.getElementById('menu')
	menu.appendChild(menuObject)
}
*{
	margin: 0;
	padding: 0;
	box-sizing: border-box;
}

button{
	padding: 40px;
}

.bounds{
	position: absolute;
	border: 2px dashed black;
	width: 10%;
	right: 8px;
	bottom: 8px;
	height: 60%;
	box-sizing: content-box;
}

.menu{
	position: absolute;
	width: 10%;
	right: 10px;
	bottom: 10px;

	background-color: chocolate;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: flex-end;
}

.menu-element{
	width: 100%;

	background-color: dodgerblue;
	margin: 5%;
}

.menu-element::before{
	content: "";
	padding-top: 100%;
	display: block;
}
<body>
	<button onclick="add()">Add item</button>
	<div class="bounds">
		Items should never leave this box
	</div>
	<div id="menu" class="menu"></div>

</body>

I have tried setting a max-height attribute to the menu, but that doesn't modify its width which is, ultimately, the value that controls the whole sizing schema. I'm looking for a CSS only solution, if it's at all possible, and any light that can be shed on the issue will be greatly appreciated.

Upvotes: 0

Views: 246

Answers (2)

leuquim
leuquim

Reputation: 655

If you want the menu to be contained by some bounds, it should be placed within these bounds so it can expand into them.

As the menu is display: flex, we can have child elements share the available space within the menu by adding flex: 1 to them.

We can optionally add a max-height value to the menu items if we want to.

add = () => {
  const menuObject = document.createElement('div')
  menuObject.classList.add('menu-element')
  const menu = document.getElementById('menu')
  menu.appendChild(menuObject)
}
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

button {
  padding: 40px;
}

.bounds {
  position: absolute;
  border: 2px dashed black;
  width: 10%;
  right: 8px;
  bottom: 8px;
  height: 60%;
  box-sizing: content-box;
}

.menu {
  width: 100%; /* Expand into boundaries */
  height: 100%; /* Expand into boundaries */
  background-color: chocolate;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
}

.menu-element {
  flex: 1; /* Makes elements expand into available space */       
  max-height: 25%; /* Height cap in case we want to have a set initial size  */
  width: 100%;
  background-color: dodgerblue;
  outline: 1px solid red; /* Help visualize boundaries */
}
<button onclick="add()">Add item</button>
<div class="bounds">
  <div id="menu" class="menu"></div> <!-- Move menu into boundaries -->
</div>

Upvotes: 1

K4R1
K4R1

Reputation: 885

Set the container div's overflow to overflow: auto

.bounds { overflow: auto; } // for example

This will give scroll bars should the items inside exit the container borders.

Also, the flex-shrink property specifies how the item will shrink relative to the rest of the flexible items inside the same container. If the element is not a flexible item, the flex-shrink property has no effect.

Set element flexible with display: flex;

flex-shrink: number|initial|inherit; // Syntax

for example if you had flexible paragraphs:

p:nth-of-type(2){flex-shrink: 3;} //Second flex-item shrinks 3x more than the rest

number = A number specifying how much the item will shrink relative to the rest of the flexible items. Default value is 1.

initial = Sets this property to its default value.

inherit = Inherits this property from its parent element.

https://www.w3schools.com/CSSref/css3_pr_flex-shrink.asp flex-shrink guide

https://www.w3schools.com/CSSref/pr_pos_overflow.asp overflow guide

Upvotes: 0

Related Questions