Joshua Kravitz
Joshua Kravitz

Reputation: 2865

How to get floated divs (with unknown width) to stay on one line

Here's the markup:

<nav id="the-nav">
    <span id="backward"><i class="icon-backward"></i></span>
    <div class="dropdown">
        <a class="dropdown-toggle" data-toggle="dropdown" href="#">
            <span class="active-module"></span>
        </a>
        <ul class="dropdown-menu">
            <li>
                <a href="#"><img src="..."></a>
             </li>
            <li>
                <a href="#"><img src="..."></a>
            </li>
        </ul>
    </div>

    <div class="wrapper">
        <div class="modules">
            <div class="module active">
                <a href="..."><i class="icon-*"></i></a> <!-- a few bootstrap icons are used -->
                <a href="..."><i class="icon-*"></i></a>
                <a href="..."><i class="icon-*"></i></a>
            </div>
            <div class="module">
                <a href="..."><i class="icon-*"></i></a>
                <a href="..."><i class="icon-*"></i></a>
                <a href="..."><i class="icon-*"></i></a>
                <!-- More items here... -->
            </div>

            <!-- More modules here... --> 

        </div>
    </div>

    <span id="forward"><i class="icon-forward"></i></span>
</nav>

And here's the less/css:

#the-nav {
  @itemDimension: 35px;
  @dropdownWidth: 150px;

  background: white;
  bottom: 0;
  left: 0;
  position: fixed;
  width: 100%;

  /* Square mixin for items and navigator arrows. */
  .square () {
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    -ms-box-sizing: border-box;
    box-sizing: border-box;
    height: @itemDimension;
    padding: 3px;
    width: @itemDimension;
  }

  div, span { float: left; }

  /* Module Dropdown */
  .dropdown {
    font-size: 12px;
    white-space: nowrap;
    width: @dropdownWidth;

    /* Make dropdown drop "up". */
    &.open > .dropdown-menu {
      bottom: 100%;
      top: inherit;
    }

    .active-module {
      overflow: hidden;
      text-overflow: ellipsis;
      width: @dropdownWidth;
    }

    img {
      height: 30px;
      width: 30px;
    }
  }

  .wrapper {
    overflow: hidden;
    position: relative;
    white-space: nowrap;

    /* Set width so that there is just enough room for the forward and back
     * arrows. As a fallback, give it a percentage width. */
    width: 88%;
    width: -webkit-calc(100% ~'-' 2*@itemDimension+@dropdownWidth);
    width: -moz-calc(100% ~'-' 2*@itemDimension+@dropdownWidth);
    width: calc(100% ~'-' 2*@itemDimension+@dropdownWidth);
  }

  /* Forward/backward scoll buttons */
  #forward, #backward {
    .square;
    padding: 7px 0 0 10px;

    &:hover {
      background: lightblue;
    }
  }

  /* Module items */
  .module > a {  
    .square;
    float: left;
    text-align: center;

    i {
      display: block !important;
      font-size: 120%;
      margin-top: 6px !important;
    }
  }

  .module:not(.active) { display: none; }
}

The module shown (determined by the dropdown) is set using javascript.

I want this entire navbar to stay on one line. Currently, it works in Chrome, but not in Firefox. In Firefox, the contents of each module wrap to a new line so that the entire navbar spans multiple lines. I want this to all stay on one line.

I have a feeling there is some combination of display, float, and white-space that will get what I want, but I am not sure what that combination that is.

UPDATE Here is a codepen that shows exactly what I want. Again, this works on chrome, but not on firefox. http://codepen.io/anon/pen/Bolnd

Upvotes: 2

Views: 1104

Answers (1)

falsarella
falsarella

Reputation: 12447

Remove the float: left and add display: inline-block; to div, span:

div, span { display: inline-block; }

Recalculate the .wrapper width considering the paddings:

width: calc(100% ~'-' 2*@itemDimension+@dropdownWidth+2*@itemPadding+2*@directionalLeftPadding);

See the Codepen with the changes


Full CSS LESS code:

/* Bootstrap */
@import url('http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.no-icons.min.css');
/* FontAwesome */
@import url('http://netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css');

@directionalLeftPadding: 10px;
@itemPadding: 3px;
@itemDimension: 35px;
@dropdownWidth: 150px;

.square () {
  box-sizing: border-box;
  height: @itemDimension;
  padding: @itemPadding;
  width: @itemDimension;
}

div, span { display: inline-block; }

nav {
  bottom: 0;
  position: fixed;
  width: 100%;
}

/* Module Dropdown */
.dropdown {
  float: left;
  font-size: 12px;
  white-space: nowrap;
  width: @dropdownWidth;

  /* Make dropdown drop "up". */
  &.open > .dropdown-menu {
    top: inherit;
    bottom: 100%;
  }

  .active-module {
    width: @dropdownWidth;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  img {
    width: 30px;
    height: 30px;
  }
}

.wrapper {
  float: left;
  overflow: hidden;
  white-space: nowrap;
  position: relative;

  /* Set width so that there is just enough room
   * for the forward and back arrows. As a
   * fallback, give it a percentage width. */
  width: 88%;
  width: -webkit-calc(100% ~'-' 2*@itemDimension+@dropdownWidth+2*@itemPadding+2*@directionalLeftPadding);
  width: -moz-calc(100% ~'-' 2*@itemDimension+@dropdownWidth+2*@itemPadding+2*@directionalLeftPadding);
  width: calc(100% ~'-' 2*@itemDimension+@dropdownWidth+2*@itemPadding+2*@directionalLeftPadding);
}

/* Forward/backward scoll buttons */
#forward, #backward {
  float: left;
  .square;
  padding: 7px 0 0 @directionalLeftPadding;

  &:hover {
    background: lightblue;
  }
}

/* Module items */
.module > span {  
  .square;
  text-align: center;

  &:not(:last-child) { border-right: 1px solid black; }

  i {
    display: block !important;
    font-size: 120%;
    margin-top: 6px !important;
  }
}

.module:not(.active) { display: none; }

Upvotes: 1

Related Questions