0

I have a problem using bootstrap 4 (specifically, reactstrap but I can recreate the same issue in bootstrap) where I am using 'card-columns' to create a grid of cards, each card having a dropdown menu in the 'card-footer'. The problem is that once I have 4 or more cards the dropdown appears to break across columns somehow....where it is rendered is different to where chrome highlights the element, as shown by this image:

enter image description here

If I increase my card count, then on some cards when I open the dropdown, the card will change position - they 'jump around'.

Minimal example:

body {
  margin: 10px;
}

.dropdown-menu {
  margin-top: 10px;
  margin-bottom: 10px;
}
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">


<div class="container-fluid h-100">
  <div class="mx-4 my-2 row">
    <div class="mx-4 row">
      <div class="card-columns">
        <div class="card border-secondary">
          <div class="card-footer">
            <div class="row">
              <div class="col-md-8">
                <div class="btn-group show">
                  <button class="dropdown-toggle btn btn-outline-secondary">
                   More
                  </button>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="card border-secondary">
          <div class="card-footer">
            <div class="row">
              <div class="col-md-8">
                <div class="btn-group show">
                  <button class="dropdown-toggle btn btn-outline-secondary">
                   More
                </button>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="card border-secondary">
          <div class="card-footer">
            <div class="row">
              <div class="col-md-8">
                <div class="btn-group show">
                  <button class="dropdown-toggle btn btn-outline-secondary">
                   More
                </button>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="card border-secondary">
          <div class="card-footer">
            <div class="row">
              <div class="col-md-8">
                <div class="btn-group show">
                  <button class="dropdown-toggle btn btn-outline-secondary">
                   More
                </button>
                  <div role="menu" class="dropdown-menu show" x-placement="bottom-start" style="position: absolute; will-change: transform; top: 0px; left: 0px; transform: translate3d(0px, 27px, 0px);" data-placement="bottom-start">
                    <button class="dropdown-item">
                      Button 1
                    </button>
                    <button class="dropdown-item">
                      Button 2
                    </button>
                    <button class="dropdown-item">
                      Button 3
                    </button>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="card border-secondary">
          <div class="card-footer">
            <div class="row">
              <div class="col-md-8">
                <div class="btn-group show">
                  <button class="dropdown-toggle btn btn-outline-secondary">
                   More
                </button>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

In this example, only the last 2 buttons of the menu seem to 'break' and appear elsewhere - your screen needs to be wide enough to show more than 1 column for the problem to occur.

I imagine the problem is to do with the dropdown extending beyond the cards' boundaries when opened, even though it is absolutely positioned.

How can I make such a dropdown without it interfering with the card-columns layout?

Carol Skelly
  • 351,302
  • 90
  • 710
  • 624
jramm
  • 6,415
  • 4
  • 34
  • 73
  • See the [Bootstrap docs](http://getbootstrap.com/docs/4.1/layout/grid/) **"Rows are wrappers for columns... In a grid layout, content must be placed within columns and only columns may be immediate children of rows."** Also see: https://stackoverflow.com/questions/45521269 The markup you posted doesn't seem to repro the issue: https://www.codeply.com/go/GZsmitJwWu – Carol Skelly Sep 07 '18 at 10:21

1 Answers1

2

The cause of this seems to be the card-columns. Those columns are made using CSS columns, and altering the display of content in them, e.g. a dropdown seems to cause them to jump all over the place.

I've created a simpler version of your code to try and demonstrate this. In version 1, when you click the dropdown toggles the columns jump around. I've added a commented block of CSS that overrides that to prove that it's the cause. If you uncomment that it works (using flexbox).

So, I'd suggest instead of using card-column, you use the Bootstrap grid. This won't give you the masonry effect though, but it's better than the oddity you have got.

/** Click that version 1 dropdowns.
    The layout jumps around.
    I think that's because of the logic behind the scenes of       CSS columns.
    Uncomment the below to prove that columns is the cause. 
    Don't actually do it in your code.
    Instead, consider using the bootstrap grid instead of card columns.
**/

/* .card-columns {
  column-count: auto !important;
  display: flex;
  flex-wrap: wrap;
}

.card-columns > * {
  flex: 0 1 33.3%;
} */
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">

<h2>Version 1 - CSS Columns</h2>
<div class="card-columns">
  <div class="card">
    <div class="row">
      <div class="col-md-8">
        <div class="btn-group">
          <button class="btn btn-secondary btn-sm dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
            Small button
          </button>
          <div class="dropdown-menu">
            <a href="#" class="dropdown-item">item</a>
            <a href="#" class="dropdown-item">item</a>
            <a href="#" class="dropdown-item">item</a>
          </div>
        </div>
      </div>
    </div>
  </div>
  
  <div class="card">
    <div class="row">
      <div class="col-md-8">
        <div class="btn-group">
          <button class="btn btn-secondary btn-sm dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
            Small button
          </button>
          <div class="dropdown-menu">
            <a href="#" class="dropdown-item">item</a>
            <a href="#" class="dropdown-item">item</a>
            <a href="#" class="dropdown-item">item</a>
          </div>
        </div>
      </div>
    </div>
  </div>
  
  <div class="card">
    <div class="btn-group">
      <button class="btn btn-secondary btn-sm dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
        Small button
      </button>
      <div class="dropdown-menu">
        <a href="#" class="dropdown-item">item</a>
        <a href="#" class="dropdown-item">item</a>
        <a href="#" class="dropdown-item">item</a>
      </div>
    </div>
  </div>
</div>

<h2>Version 2 - Grid</h2>
<div class="row">
  <div class="col-md-4">
    <div class="card">
      <div class="row">
        <div class="col-md-8">
          <div class="btn-group">
            <button class="btn btn-secondary btn-sm dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
              Small button
            </button>
            <div class="dropdown-menu">
              <a href="#" class="dropdown-item">item</a>
              <a href="#" class="dropdown-item">item</a>
              <a href="#" class="dropdown-item">item</a>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
  
  <div class="col-md-4">
    <div class="card">
      <div class="row">
        <div class="col-md-8">
          <div class="btn-group">
            <button class="btn btn-secondary btn-sm dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
              Small button
            </button>
            <div class="dropdown-menu">
              <a href="#" class="dropdown-item">item</a>
              <a href="#" class="dropdown-item">item</a>
              <a href="#" class="dropdown-item">item</a>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
  
  <div class="col-md-4">
    <div class="card">
      <div class="row">
        <div class="col-md-8">
          <div class="btn-group">
            <button class="btn btn-secondary btn-sm dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
              Small button
            </button>
            <div class="dropdown-menu">
              <a href="#" class="dropdown-item">item</a>
              <a href="#" class="dropdown-item">item</a>
              <a href="#" class="dropdown-item">item</a>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
davidpauljunior
  • 8,238
  • 6
  • 30
  • 54
  • Thanks. I feared this was the case - that I will have to stop using css-columns. In fact, using the grid is more than acceptable since the cards will always have the same dimensions. – jramm Sep 07 '18 at 12:21
  • No problem. Could you mark the answer as correct if you're happy with it? :) – davidpauljunior Sep 07 '18 at 13:06