简体   繁体   中英

Absolute flexbox container's width

How to get an absolute-positioned flex container to take the correct width based on its content? I've spent hours with this example but haven't been able to figure out what the problem is. This is what I've ended up with:

在此处输入图片说明

Code from the example:

 .container { padding-right: 0; padding-left: 0; max-width: 1170px; margin: 0 auto; box-shadow: 0 0 5px rgba(0, 0, 0, 0.1); background: white; } .nav { background: #f8f8f8; min-height: 3.57143rem; } .nav__root { margin: 0; list-style: none; display: flex; flex-flow: row nowrap; } .nav__root ul { list-style: none; margin: 0; } .nav__root li { letter-spacing: 1px; font-size: 1rem; text-align: center; line-height: 2.0; color: #777; font-weight: 100; } .nav__root li a { color: #777; } .nav__root li a:hover { color: #333; } .nav__dropdown { flex: 0 0 auto; position: relative; } .nav__toggle { text-transform: uppercase; padding: 1.07143rem; display: block; position: relative; } .nav__menu { display: flex; flex-flow: row nowrap; position: absolute; top: 100%; left: 0; min-width: 14.28571rem; padding: 0.35714rem 0; margin: 0.14286rem 0 0; font-size: 1rem; background-color: #fff; border: 1px solid rgba(0, 0, 0, 0.15); border-radius: 0 0 4px 4px; box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); background-clip: padding-box; } .nav__submenu { flex: 0 0 auto; width: auto; margin-right: 1.07143rem; margin-left: 1.07143rem; } .nav__separator { height: 1px; margin: 9px 0; overflow: hidden; background-color: #e5e5e5; } .nav-level--1>li>a { text-transform: uppercase; } 
 <div class="container"> <nav class="nav"> <ul class="nav__root"> <li class="first nav__dropdown"> <a href="#" class="nav__toggle"> <strong>Foo</strong> <b class="caret"></b> </a> <ul class="nav__menu"> <li class="first"> <a href="#">Foo</a> </li> <li> <a href="#">Bar</a> </li> <li class="last"> <a href="#">Baz</a> </li> </ul> </li> <li class="nav__dropdown"> <a href="#" class="nav__toggle"> <strong>Bar</strong> <b class="caret"></b> </a> <ul class="nav__menu"> <li class="first nav__submenu"> <a href="#" class="nav__toggle"> <strong>Foo</strong> <b class="caret"></b> </a> <ul class="nav-level--2"> <li class="first"> <a href="#">Foo Foo Foo Foo </a> </li> <li> <a href="#">Bar Bar Bar Bar </a> </li> <li class="last"> <a href="#">Baz Baz Baz Baz </a> </li> </ul> </li> <li class="nav__submenu"> <a href="#" class="nav__toggle"> <strong>Bar</strong> <b class="caret"></b> </a> <ul class="nav-level--2"> <li class="first"> <a href="#">Foo Foo Foo Foo </a> </li> <li> <a href="#">Bar Bar Bar Bar </a> </li> <li class="last"> <a href="#">Baz Baz Baz Baz </a> </li> </ul> </li> <li class="last nav__submenu"> <a href="#" class="nav__toggle"> <strong>Baz</strong> <b class="caret"></b> </a> <ul class="nav-level--2"> <li class="first"> <a href="#">Foo Foo Foo Foo </a> </li> <li> <a href="#">Bar Bar Bar Bar </a> </li> <li class="last"> <a href="#">Baz Baz Baz Baz </a> </li> </ul> </li> </ul> </li> <li class="last nav__dropdown"> <a href="#" class="nav__toggle"> <strong>Baz</strong> <b class="caret"></b> </a> <ul class="nav__menu"> <li class="first nav__submenu"> <a href="#" class="nav__toggle"> <strong>Foo</strong> <b class="caret"></b> </a> <ul class="nav-level--2"> <li class="first"> <a href="#">Foo Foo Foo Foo </a> </li> <li> <a href="#">Bar Bar Bar Bar </a> </li> <li class="last"> <a href="#">Baz Baz Baz Baz </a> </li> </ul> </li> <li class="nav__submenu"> <a href="#" class="nav__toggle"> <strong>Bar</strong> <b class="caret"></b> </a> <ul class="nav-level--2"> <li class="first"> <a href="#">Foo Foo Foo Foo </a> </li> <li> <a href="#">Bar Bar Bar Bar </a> </li> <li class="last"> <a href="#">Baz Baz Baz Baz </a> </li> </ul> </li> <li class="last nav__submenu"> <a href="#" class="nav__toggle"> <strong>Baz</strong> <b class="caret"></b> </a> <ul class="nav-level--2"> <li class="first"> <a href="#">Foo Foo Foo Foo </a> </li> <li> <a href="#">Bar Bar Bar Bar </a> </li> <li class="last"> <a href="#">Baz Baz Baz Baz </a> </li> </ul> </li> </ul> </li> </ul> </nav> </div> 

Here's the problem:

The containing block of an absolutely-positioned element is the nearest positioned ancestor.

In this case, that means that the width of your drop-down menus ( position: absolute ) are confined to the width of the main nav items ( position: relative ).

So, for the drop-downs to expand beyond their containing blocks, you will either (1) need to remove the positioning from the nav items and place it at a higher level, such as the nav bar. But this can get messy. You'll need to re-position all absolutely positioned drop-downs; (2) add width to the main nav items; (3) try a different method.

More about CSS positioning: https://developer.mozilla.org/en-US/docs/Web/CSS/position

width:max-content , give this property to your class nav__menu

This will work perfect for you.

 .container { padding-right: 0; padding-left: 0; max-width: 1170px; margin: 0 auto; box-shadow: 0 0 5px rgba(0, 0, 0, 0.1); background: white; } .nav { background: #f8f8f8; min-height: 3.57143rem; } .nav__root { margin: 0; list-style: none; display: flex; flex-flow: row nowrap; } .nav__root ul { list-style: none; margin: 0; } .nav__root li { letter-spacing: 1px; font-size: 1rem; text-align: center; line-height: 2.0; color: #777; font-weight: 100; } .nav__root li a { color: #777; } .nav__root li a:hover { color: #333; } .nav__dropdown { flex: 0 0 auto; position: relative; } .nav__toggle { text-transform: uppercase; padding: 1.07143rem; display: block; position: relative; } .nav__menu { display: flex; flex-flow: row nowrap; position: absolute; width: max-content; top: 100%; left: 0; min-width: 14.28571rem; padding: 0.35714rem 0; margin: 0.14286rem 0 0; font-size: 1rem; background-color: #fff; border: 1px solid rgba(0, 0, 0, 0.15); border-radius: 0 0 4px 4px; box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); background-clip: padding-box; } .nav__submenu { flex: 0 0 auto; width: auto; margin-right: 1.07143rem; margin-left: 1.07143rem; } .nav__separator { height: 1px; margin: 9px 0; overflow: hidden; background-color: #e5e5e5; } .nav-level--1>li>a { text-transform: uppercase; } 
 <div class="container"> <nav class="nav"> <ul class="nav__root"> <li class="first nav__dropdown"> <a href="#" class="nav__toggle"> <strong>Foo</strong> <b class="caret"></b> </a> <ul class="nav__menu"> <li class="first"> <a href="#">Foo</a> </li> <li> <a href="#">Bar</a> </li> <li class="last"> <a href="#">Baz</a> </li> </ul> </li> <li class="nav__dropdown"> <a href="#" class="nav__toggle"> <strong>Bar</strong> <b class="caret"></b> </a> <ul class="nav__menu"> <li class="first nav__submenu"> <a href="#" class="nav__toggle"> <strong>Foo</strong> <b class="caret"></b> </a> <ul class="nav-level--2"> <li class="first"> <a href="#">Foo Foo Foo Foo </a> </li> <li> <a href="#">Bar Bar Bar Bar </a> </li> <li class="last"> <a href="#">Baz Baz Baz Baz </a> </li> </ul> </li> <li class="nav__submenu"> <a href="#" class="nav__toggle"> <strong>Bar</strong> <b class="caret"></b> </a> <ul class="nav-level--2"> <li class="first"> <a href="#">Foo Foo Foo Foo </a> </li> <li> <a href="#">Bar Bar Bar Bar </a> </li> <li class="last"> <a href="#">Baz Baz Baz Baz </a> </li> </ul> </li> <li class="last nav__submenu"> <a href="#" class="nav__toggle"> <strong>Baz</strong> <b class="caret"></b> </a> <ul class="nav-level--2"> <li class="first"> <a href="#">Foo Foo Foo Foo </a> </li> <li> <a href="#">Bar Bar Bar Bar </a> </li> <li class="last"> <a href="#">Baz Baz Baz Baz </a> </li> </ul> </li> </ul> </li> <li class="last nav__dropdown"> <a href="#" class="nav__toggle"> <strong>Baz</strong> <b class="caret"></b> </a> <ul class="nav__menu"> <li class="first nav__submenu"> <a href="#" class="nav__toggle"> <strong>Foo</strong> <b class="caret"></b> </a> <ul class="nav-level--2"> <li class="first"> <a href="#">Foo Foo Foo Foo </a> </li> <li> <a href="#">Bar Bar Bar Bar </a> </li> <li class="last"> <a href="#">Baz Baz Baz Baz </a> </li> </ul> </li> <li class="nav__submenu"> <a href="#" class="nav__toggle"> <strong>Bar</strong> <b class="caret"></b> </a> <ul class="nav-level--2"> <li class="first"> <a href="#">Foo Foo Foo Foo </a> </li> <li> <a href="#">Bar Bar Bar Bar </a> </li> <li class="last"> <a href="#">Baz Baz Baz Baz </a> </li> </ul> </li> <li class="last nav__submenu"> <a href="#" class="nav__toggle"> <strong>Baz</strong> <b class="caret"></b> </a> <ul class="nav-level--2"> <li class="first"> <a href="#">Foo Foo Foo Foo </a> </li> <li> <a href="#">Bar Bar Bar Bar </a> </li> <li class="last"> <a href="#">Baz Baz Baz Baz </a> </li> </ul> </li> </ul> </li> </ul> </nav> </div> 

I've solved the problem this way: the backend renderer generates classes like nav__menu--1 , nav__menu--2 and so on depending on the number of columns in a menu. On the other end SASS generates particular widths for every class based on the width of one menu column:

$menu-column-width: rem-calc(200px);

@for $i from 1 through 6 {
  .nav__menu--#{$i} {
    width: $menu-column-width * $i;
  }
}

So I've ended up with hardcoded widths which works just fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM