Search code examples
htmlcsssassz-indextranslate-animation

What could be causing translated div elements to NOT overlap surrounding content?


The effect I'm trying to achieve is rather simple. When the user hovers over elements within a div that's located across the bottom of the page, the "card" slides up, bringing more content into view.

Whenever I create "test" pages on jsfiddle, it works as I'd expect. Here's a link to an example Simply hover over the bottom button or yellow div box for them to translate upward and "cover" the main body of the page (code snippets shared at the end of this post).

However, whenever I try to implement this within my own project, the hovered elements do slide upward, but they do NOT overlap on top of the remaining page. Here's a screenshot illustrating the problem.

I've tried to strip down the layout and contents to virtually nothing (removed Bootstrap and flexbox related content, removed animations from the main center area, removed canvas elements, etc) but still the issue persists.

As far as I can tell, all z-index and stacking contexts are good... For example, the bottom-panel in question does render on top of the previous elements in the flow, but the "slide-up" portion still gets "cut-off" by the containing div rather than "overlap" above the previous portions of the page.

Any idea what could cause this behavior? Anything I may be overlooking?

Here are some code snippets from my "gutted" testbed. The "main" div is even now just a blank classless div, no container or flexbox, etc.

application.html.erb

<!DOCTYPE html>
<html>
<head>
  <%= render 'layouts/head' %>
  <%= render 'layouts/shim' %>
</head>
<body class="<%= controller.controller_name %>">
  <div id="wrapper">
    <%= render 'layouts/header' %>
    <div>

      <% flash.each do |message_type, message| %>
        <%= content_tag(:div, message, class: "alert alert-#{message_type}") %>
      <% end %>
      <br />

      <%= yield %>

      <%= render 'tasks/bottom_panel' %>
    </div>

    <%= <%= render 'layouts/footer' %1> %>
    <%= debug(params) if Rails.env.development? %>
  </div>
</body>
</html>

tasks/_bottom_panel.html.erb

<div id="bottom-panel">
  <div id="test"></div>
  <div id="test2"></div>
  <%= button_tag "TESTING", class:"btn btn-med btn-primary" %>
</div>

Images index page (shown in the example screenshot)

<h1>Images</h1>

<table>
  <thead>
    <tr>
      <!-- <th colspan="3"></th> -->
    </tr>
  </thead>

  <tbody>
    <% @images.each do |image| %>
      <tr>
        <td><%= image.id %></td>
        <td><%= image_tag image.file_url(:mini)  %></td>
        <td><%= link_to 'Show', image %></td>
        <td><%= link_to 'Edit', edit_image_path(image) %></td>
        <td><%= link_to 'Destroy', image, method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <% end %>
  </tbody>
</table>

SCSS (NOTE: trying ridiculous z-index values, and mixing in a "float" just to see if either works)

#bottom-panel {
  height: auto;
  width: 100%;
  // height: 60px;

  background-color: $background-grey;
  // width: calc(100% - #{$right-panel-width});
  // max-width: calc(100% - #{$right-panel-width});

  // position: absolute;
  position: fixed;
  bottom: 0;
  left: 0;

  z-index: 6;

  margin: 0;
  overflow: hidden;

  #test {
    display: inline-block;

    float: left;

    z-index: 20;

    height: 300px;
    width: 300px;
    background: green;

    &:hover {
      transform: translate(0%, -10%);
      transition-duration: 100ms;
    }
  }

  #test2 {
    display: inline-block;

    float: left;

    height: 300px;
    width: 300px;
    background: red;

    &:hover {
      transform: translate(0%, -10%);
      transition-duration: 100ms;
    }
  }

  .btn {
    height: 200px;

    &:hover {
      transform: translate(0%, -10%);
      transition-duration: 100ms;
    }
  }

jsfiddle code

HTML

<div id="main">
  <div id="bottom-navbar">
    <button class="btn btn-med btn-primary">
      BUTTON!
    </button>
    <div id="test-div"></div>
  </div>
</div>

SCSS

$bottom-navbar-height: 50px;

#main {
  margin: 0;
  padding: 0;
  width: 100%;
  height: calc(100vh - #{$bottom-navbar-height});
  background: green;
}

#bottom-navbar {
  position: fixed;
  bottom: 0;
  left: 0;
  width: 100%;
  height: $bottom-navbar-height;
  background: blue;

  .btn {
    height: 40px;
    display: inline-block;
    vertical-align: top;

    &:hover {
      transform: translate(0px, -10px);
    }
  }

  #test-div {
    height: 50px;
    width: 80px;
    display: inline-block;
    background: yellow;

    &:hover {
      transform: translate(0px, -10px);
    }
  }
}

Solution

  • Your combined style:

    #bottom-panel {
        height: $bottom-navbar-height;
        overflow: hidden;
    }
    

    forces browser to clip the content, which affects your button and div transformations. Docs say:

    Content is clipped if necessary to fit the padding box.

    Just remove overflow property and it will work as expected.