Ruslan
Ruslan

Reputation: 1303

How to force child elements to expand the parent element?

I make a drop-down menu with a lot of items (I don't know exactly how many).

I expect the child <ul> to expand to max-width when it has enough items, but actually it expands to parent <div>'s width only, no more.

Why?

Upd: I want to break long lines, not to shrink them by flex.

Upd 2: I want to the child <ul> to be not smaller than the parent <div>.

div {
  background: aquamarine;
  height: 50px;
  position: relative;
  width: 200px;
}

ul {
  background: blue;
  list-style-type: none;
  margin: 0;
  max-width: 500px;
  padding: 5px;
  position: absolute;
  top: 100%;
}

li {
  background: yellow;
  margin: 5px;
  padding: 5px;
}

a {
  background: red;
  color: white;
  display: inline-block;
  margin: 5px;
  width: 30px;
}
<div>
  <ul>
    <li>
      <a>A</a>
      <a>B</a>
    </li>
    <li>
      <a>A</a>
      <a>B</a>
      <a>C</a>
      <a>D</a>
      <a>E</a>
      <a>F</a>
      <a>G</a>
      <a>H</a>
      <a>I</a>
    </li>
  </ul>
</div>

Upvotes: 3

Views: 2402

Answers (5)

Danield
Danield

Reputation: 125423

FWIW: An additional option not mentioned yet:

Use intrinsic sizing for the width:

ul {
  ...
  width: max-content;
  max-width: 500px;
  ...
}

From the spec:

max-content If specified for the inline axis, use the max-content inline size; otherwise compute to auto.

NB: you can use max-width: 500px in conjunction with the width property to ensure that the content width never exceeds 500px (max-width will override width).

div {
  background: aquamarine;
  height: 50px;
  position: relative;
  width: 200px;
}

ul {
  background: blue;
  list-style-type: none;
  margin: 0;
  width: -moz-max-content;
  width: -webkit-max-content;
  width: max-content;
  max-width: 500px;
  padding: 5px;
  position: absolute;
  top: 100%;
}

li {
  background: yellow;
  margin: 5px;
  padding: 5px;
}

a {
  background: red;
  color: white;
  display: inline-block;
  margin: 5px;
  width: 30px;
}
<div>
  <ul>
    <li>
      <a>A</a>
      <a>B</a>
    </li>
    <li>
      <a>A</a>
      <a>B</a>
      <a>C</a>
      <a>D</a>
      <a>E</a>
      <a>F</a>
      <a>G</a>
      <a>H</a>
      <a>I</a>
      <a>A</a>
      <a>B</a>
      <a>C</a>
      <a>D</a>
      <a>E</a>
      <a>F</a>
      <a>G</a>
      <a>H</a>
      <a>I</a>
    </li>
  </ul>
</div>

Browser Support is also pretty good (Except for IE/Edge)

Upvotes: 0

Carl Binalla
Carl Binalla

Reputation: 5401

You want something like this? I changed the width: 200px of div to max-width:500px and removed the max-width:500px in ul

div {
  background: aquamarine;
  height: 50px;
  position: relative;
  max-width: 500px;
}

ul {
  background: blue;
  list-style-type: none;
  margin: 0;
  padding: 5px;
  position: absolute;
  top: 100%;
}

li {
  background: yellow;
  margin: 5px;
  padding: 5px;
}

a {
  background: red;
  color: white;
  display: inline-block;
  margin: 5px;
  width: 30px;
}
<div>
  <ul>
    <li>
      <a>A</a>
      <a>B</a>
    </li>
    <li>
      <a>A</a>
      <a>B</a>
      <a>C</a>
      <a>D</a>
      <a>E</a>
      <a>F</a>
      <a>G</a>
      <a>H</a>
      <a>I</a>
      <a>E</a>
      <a>F</a>
      <a>G</a>
      <a>H</a>
      <a>I</a>
    </li>
  </ul>
</div>

Upvotes: -1

Pete
Pete

Reputation: 58412

You can move the relative positioning up to a parent element that is wide enough to handle the 500px:

div.wide-load {
  width: 500px;
  position: relative;
}

div.direct-parent {
  background: aquamarine;
  height: 50px;
  width: 200px;
}

ul {
  background: blue;
  list-style-type: none;
  margin: 0;
  max-width: 500px;
  padding: 5px;
  position: absolute;
  top: 100%;
}

li {
  background: yellow;
  margin: 5px;
  padding: 5px;
}

a {
  background: red;
  color: white;
  display: inline-block;
  margin: 5px;
  width: 30px;
}
<div class="wide-load">
  <div class="direct-parent">
    <ul>
      <li>
        <a>A</a>
        <a>B</a>
      </li>
      <li>
        <a>A</a>
        <a>B</a>
        <a>C</a>
        <a>D</a>
        <a>E</a>
        <a>F</a>
        <a>G</a>
        <a>H</a>
        <a>I</a>
      </li>
    </ul>
  </div>
</div>

If you are unable to do this, then your only other option is to make the li's white-space:nowrap - but this will not respect your max-width:

div.direct-parent {
  background: aquamarine;
  position: relative;
  height: 50px;
  width: 200px;
}

ul {
  background: blue;
  list-style-type: none;
  margin: 0;
  max-width: 500px;
  padding: 5px;
  position: absolute;
  top: 100%;
}

li {
  background: yellow;
  margin: 5px;
  padding: 5px;
  white-space: nowrap;
}

a {
  background: red;
  color: white;
  display: inline-block;
  margin: 5px;
  width: 30px;
}
<div class="direct-parent">
  <ul>
    <li>
      <a>A</a>
      <a>B</a>
    </li>
    <li>
      <a>A</a>
      <a>B</a>
      <a>C</a>
      <a>D</a>
      <a>E</a>
      <a>F</a>
      <a>G</a>
      <a>H</a>
      <a>I</a>
    </li>
  </ul>
</div>

Upvotes: 2

Sudik Maharana
Sudik Maharana

Reputation: 714

li {
    background: yellow none repeat scroll 0 0;
    display: flex;
    margin: 5px;
    padding: 5px;
}

You can use

display: flex;

Upvotes: 1

roberrrt-s
roberrrt-s

Reputation: 8210

It's the principle of max-width. You force an item to never be larger than the specified unit, but this doesn't automatically mean that your element will ever reach that length. In this case, your absolutely positioned <ul> is still restricted to it's initial parent, which forces it to be a maximum of 200px long.

Upvotes: 0

Related Questions