How to achive certain overlapping layout when there is not enough space in parent container?


Tags: html,css,css3

Problem :

I have <div class="parent" style="position: relative; width: 100%; height: 25vh;">...</div> that contains some amount of <div class="child"></div> elements (the number of them vary between sub-pages). As you see the size of .parent is known but not fixed. The .child size is fixed to e.g. 100px x 170px.

When there is enough space for all children in .parent, I want to place them one next to another, row by row (it's easy with e.g. float: left;): enter image description here

But when there are too many children for .parent, I want the excessive elements to be put "above" others, with small offset (so we can see that there's something below them - in a bit similar way to a Patience card game):

enter image description here

Note the order and that those excessive elements don't have to be on any "layer"/z-index, they should just overlap the divs that are before them.

Also, there is none fixed number of cards per row, as the .parent width is 100% of client width.

How can I achieve such behavior with CSS, without JavaScript (I know I could just compute absolute x/y based on child's index in JavaScript)?



Solution :

I believe I found a pure CSS solution that might work for you. From what I understand, you the Parent Div container and a random number of child divs that represent cards.

Disclaimer: I used pixels for this to show proof of concept, but the same effect can be done by using all percents if you work out the math.

Basic HTML Layout

// I am using the <!-- comments --> to remove whitespace between divs
// This is important because we don't want to being floating elements
// So each pixel is going to count
<div class="parent">
     <div class="child">card 1</div><!--
  --><div class="child">card 2</div><!--
  --><div class="child">card 3</div><!--
  --><div class="child">card 4</div><!--
  --><div class="child">card 5</div><!--
  --><div class="child">card 6</div>
</div>

For demonstration purposes, I made the cards a nice 100px by 150px. This just helps visual the math in my opinion. Here is the basic CSS we need to layout the field.

CSS

// normalize div elements
*{ box-sizing: border-box; margin: 0; padding: 0; }

.parent{
  position: relative;
  width: 480px; //4 cards wide with 10px of margin on each side (4*100)+(4*20)
  background: blue;
  height: 340px;
  overflow:hidden;
  margin: 0px auto;
}
.child{
  position: relative;
  width: 100px;
  height: 150px;
  border:1px solid #000;
  background: #333;
  color: white;
  margin: 10px;
  display: inline-block;
}

Now that the grid is setup, we just need to move the third and forth row up.

One of the great things about CSS is you can apply styles to elements that may of may not exist on the page. Using the nth-child selector will help us target these unknown elements.

MOAR CSS

.child:nth-child(n+9){
  // move cards from their origin up 330px and left 5px
  transform: translateY(-330px) translateX(-5px);
}

The only thing you need is to create enough rules to match the multiple outcomes you may have.

Example: I need to support a possibility of 18 cards. Just add another rule!

.child:nth-child(n+17){
  // all we have to do is double the increments
  transform: translateY(-660px) translateX(-10px);
}

Hope that helps.

Working JSFiddle


    CSS Howto..

    How to show blocks for progressbar using CSS

    How to Change CSS of Custom Template JointJS Element?

    How to change order of elements inside tables?

    How to get CSS transform rotation value in degrees with JavaScript

    how to change the background color of first row in html table and all other rows alternate color

    How to have an array of images side by side using css/html

    Hide the element, but show for that place blank

    How to Create a CSS3 Animated Circle that chages colors when clicked?

    CSS rule doesn't show up in developer tools

    How to change CSS based on Season using JavaScript

    How to strach div in some line to “all left space” with css

    How do I make the link in the back div clickable

    img not showing in Safari in attempt to make img map responsive

    css: how to remove pseudo elements (after, before, …)

    div under div - dont know how to do this

    How to Vertical align text in div

    Angularjs how to add/remove dynamically input form with ng-Repeat on Google Maps?

    How to add a tooltip for just the background image of an input field with HTML and CSS

    How to write css code in javascript? (Uncaught TypeError: Cannot set property “height” of undefined)

    How to make interactive logo design without flash?

    How to use 'dynamic CSS' in Rails

    How to have a textbox with label inside it support 'tap to paste' feature in iPad?

    How to use CSS for formatting Crystal Report in Winform?

    How to do a webkit css endless rotation-animation.

    How would I replicate this input text effect where they're almost a merged box in CSS/HTML?

    How to set CSS attributes relative to a parent node?

    How to modify multiple CSS attributes of an element?

    How to reflect updates to CSS at runtime in Visual Studio 2012?

    Large white space below footer showing on certain pages on iPhone actual device but not emulator in Chrome

    How to build a simple CSS layout that expands to the viewport?