How to overlap elements in CSS grid when using "overflow:visible" - css

I have overflowing elements in a grid (overflow:hidden by default and set to overflow:visible on hover). The default stacking order of the browser in a grid is that "later" elements overlap the "earlier" elements. I would like to invert that overlapping behavior.
The only way I have achieved this so far is manually setting the z-index, so the "earlier" elements have a higher z-index than the later ones. Is there a better way to do this?
.card-container {
width: 80px;
display: grid;
grid-template-columns: repeat(1, minmax(0,1fr));
grid-gap: 10px;
background: #aaaaee;
}
.card {
padding: 5px;
height: 2em;
overflow: hidden;
}
.card:hover {
overflow: visible;
}
.bgcolor {
background-color:white;
box-shadow: 2px 2px 2px 1px rgba(0, 0, 0, .2);
}
<div class="card-container">
<div class="card" style="z-index:3">
<div class="bgcolor">
Text A1 Text A2 Text A3 Text A4 Text A5 Text A6 Text A7 Text A8
</div>
</div>
<div class="card" style="z-index:2">
<div class="bgcolor">
Text B1 Text B2 Text B3 Text B4 Text B5 Text B6 Text B7 Text B8
</div>
</div>
<div class="card" style="z-index:1">
<div class="bgcolor">
Text C1 Text C2 Text C3 Text C4 Text C5 Text C6 Text C7 Text C8
</div>
</div>
</div>

Related

CSS Grid: how to change the flow of a gird?

I haven't been able to find a solution, but it seems it should be simple enough with CSS Grid.
I have a 2x2 grid. So far, I have only:
display: grid;
grid-template-columns: 50% 50%;
My grid looks like this:
A1 A2
B1 B2
How do I change the flow so that it's:
A1 B1
A2 B2
Thank you
As Temani and David have said, you can use the grid-auto-flow property to change how grid items are placed by the grid algorithm. You'll also need to specify your rows:
.container {
display: grid;
grid-template: 50% 50% / 50%;
grid-auto-flow: column;
}
<div class="container">
<div>A1</div>
<div>A2</div>
<div>B1</div>
<div>B2</div>
</div>
You can create a code like this.
.container {
width: 100%;
background-color: coral;
display: grid;
grid-template-columns: 50% 50%;
}
.a1{
background-color: blue;
}
.a2{
backgroud-color:yellow;
}
.b1{
background-color: green;
}
.b2{
background-color: yellow;
}
<div class="container">
<div>
<div class="a1">A1</div>
<div class="a2">A2</div>
</div>
<div>
<div class="b1">b3</div>
<div class="b2">b4</div>
</div>
</div>

Evenly sized columns between rows using grid/flex

Consider the following snippet:
#container{
border: solid 1px black;
display: inline-grid;
grid-template-columns: repeat(3, auto);
}
<div id="container">
<div class="row">
<div class="item">A1111</div>
<div class="item">B1</div>
<div class="item">C1</div>
</div>
<div class="row">
<div class="item">A2</div>
<div class="item">B2222</div>
<div class="item">C2</div>
</div>
<div class="row">
<div class="item">A3</div>
<div class="item">B3</div>
<div class="item">C3333</div>
</div>
</div>
The end result is a table-like display where each item of every row is the width of the widest item in that column.
A1111 A2 A3
B1 B2222 B3
C1 C2 C3333
Which is great - but I need the table laid out as rows...
A1111 B1 C1
A2 B2222 C2
A3 B3 C3333
display: table solves this - but table has some drawbacks around spacing, alignments and so-on. Therefore, grid and flex looks attractive.
Alas I cannot figure out how to get the information laid out as desired.
Adding display: grid to .row helps the order of information, but doesn't retain the equal column widths.
The item content will vary, and so cannot use fixed widths and it is not desired that the grid/flex spans the entire page/containing width.
You can define which column the grid item should be using grid-column. This means the row doesn't require a containing row div.
Working example...
#container{
border: solid 1px black;
display: inline-grid;
grid-auto-flow: row;
grid-gap: 10px;
padding: 10px;
}
.col1{
grid-column: 1;
}
.col2{
grid-column: 2;
}
.col3{
grid-column: 3;
}
<div id="container">
<div class="col1">A11111</div>
<div class="col2">B1</div>
<div class="col3">C1</div>
<div class="col1">A2</div>
<div class="col2">B2222222</div>
<div class="col3">C2</div>
<div class="col1">A3</div>
<div class="col2">B3</div>
<div class="col3">C33333333</div>
</div>
</div>
Your main problem is your markup is too deep. You have table-like markup, three levels deep: table, rows, and cells. For grid layout, you don’t need the “row” elements at all.
When you use display: grid or display: inline-grid on an element, it makes that element a grid container. Each of its child elements then become grid items. Grid items will be laid out in the grid defined by their container.
You also said you want columns of equal width. For this, you should use the fr unit rather than auto for your column sizes:
grid-template-columns: repeat(3, 1fr);
…this will make each column one “fraction” unit wide.
#container{
border: solid 1px black;
display: inline-grid;
grid-template-columns: repeat(3, 1fr);
}
<div id="container">
<div class="item">A1111</div>
<div class="item">B1</div>
<div class="item">C1</div>
<div class="item">A2</div>
<div class="item">B2222</div>
<div class="item">C2</div>
<div class="item">A3</div>
<div class="item">B3</div>
<div class="item">C3333</div>
</div>
There's way which I would make it.
Attached JSFiddle(click)
.row {
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
}
.row > .item {
display:block;
flex: 1 1;
border: 1px solid #000;
}
There's such great guide about flex; Click here.

How to make child elements from parent1 have a higher z-index than child elements from parent 2 (with same z-index as other parent)?

I have the following HTML:
HTML
<div id="map">
<div class="parent">
<svg>
<div class="child"></div>
<div class="child"></div>
</svg>
</div>
<div class="parent">
<svg>
<div class="child"></div>
<div class="child"></div>
</svg>
</div>
</div>
CSS
.parent {
position: absolute;
top: 0;
left: 0;
width: 1000px;
height: 700px;
}
svg {
overflow: hidden;
width: 100%;
height: 100%;
}
Abbreviations:
first parent-element: p1
second parent-element: p2
child-elements from p1: c1
child-elements from p2: c2
Background info:
Both parent-elements are positioned exactly above each other. It seems that the p2 is "a complete layer above the p1".
Problem/Question:
Currently i can NOT click on ANY c1. No chance. The p2 seems to be a complete layer above the p1. How do I manage that c2 still are above c1 BUT I am able to click on c1 if there are no c2 directly above them.
You could add pointer-events: none to the .parent divs and then add pointer-events:all to the .child divs.
This would mean only the actual children can be clicked. If there is no c2 then c1 should be clickable
something like this?
http://jsfiddle.net/ekL6632c/1/

Flexbox: how to add margin / vertical spacing for the case there is more than one row?

here is the codepen
I want to add vertical spacing ONLY to elements between line 1 and line 2. Alternatively, only to between line 1 and line 2, and line 2 and line 3.
The flex items are random, so the amount, size of each, is dynamic.
I cannot add margins to all, because that would ruin the layout in case there is no second row at all.
HTML
<div class="flexContainer">
<div class="flexItem">a a a aaaaaaa a ax</div>
<div class="flexItem">bbbx</div>
<div class="flexItem">c c c c c cx</div>
<div class="flexItem">note: random amount of flex items</div>
<div class="flexItem">amount can very...</div>
</div>
<br/><br/><br/>
<div class="flexContainer">
<div class="flexItem">a a a aaaaaaa a ax</div>
<div class="flexItem">bbbx</div>
<div class="flexItem">c c c c c cx</div>
</div>
CSS
.flexContainer{
background-color: salmon;
display: flex;
flex-direction: row;
width: 300px;
flex-wrap: wrap;
}
.flexItem{
background-color: lightblue;
margin: 5px;
}
Browsersupport: only newest cutting edge browsers are supported.
You can
Add some margin-bottom to the first and last .flex-items.
Align all flex items to top with align-items: flex-start or align-self: flex-start.
Add a negative margin-bottom to .flexContainer in order to counteract the margin after the last line.
Place the .flexContainer inside a wrapper with overflow: hidden.
.wrapper {
overflow: hidden;
}
.flexContainer {
background-color: salmon;
display: flex;
flex-flow: row wrap;
width: 300px;
margin-bottom: -20px; /* 25-20 = 5 */
}
.flexItem {
background-color: lightblue;
margin: 5px;
align-self: flex-start;
}
.flexItem:first-child, .flexItem:last-child {
margin-bottom: 25px;
}
<div class="wrapper">
<div class="flexContainer">
<div class="flexItem">a a a aaaaaaa a ax</div>
<div class="flexItem">bbbx</div>
<div class="flexItem">c c c c c cx</div>
<div class="flexItem">note: random amount of flex items</div>
<div class="flexItem">amount can very...</div>
</div>
</div>
<br/><br/>
<div class="wrapper">
<div class="flexContainer">
<div class="flexItem">a a a aaaaaaa a ax</div>
<div class="flexItem">bbbx</div>
<div class="flexItem">c c c c c cx</div>
</div>
</div>

Bottom aligning div without specifying parent container height

I have some html like this
<div class="gRow">
<div class="cell c9 right last">Text</div>
<div class="cell c8 right gCol8">Long text wrapped over multiple lines</div>
<div class="cell c7 right gCol7">Text</div>
</div>
See this fiddle: http://jsfiddle.net/LmZYE/
What I would like is to have the two "Text" div's align to the bottom of the gRow div.
I don't know the height of gRow at render time as the text changes with selected language. I have tried positioning gRow relative and my inner div's absolute, bottom:0 but in vain.
Can I do what I'm trying to do or do I need to know the height of the gRow div?
EDIT: Forgot one thing: I would like to have a right border going all the way from the top to the bottom of gRow.
Thanks in advance!
If you need to do this using divs rather than a table you can use the css for display:table to make your divs respond like a table would:
html
<div class="table">
<div class="row">
<div class="cell c9 right last">Text</div>
<div class="cell c8 right gCol8">Long text wrapped over multiple lines</div>
<div class="cell c7 right gCol7">Text</div>
</div>
</div>
css
.table {display:table; border-right: 1px solid red;}
.row {display:table-row;}
.cell {border-left: 1px solid red; display:table-cell; width:33%;}
Then you can keep adding rows and cells as you please.
You are also able to take advantage of the vertical-align property for if you want to align text to the middle or bottom of the div
http://jsfiddle.net/LmZYE/6/
If I've understood the question right, this is what you're looking for.
HTML
<div class="gRow">
<div class="cell c8 right gCol8">Long text wrapped over multiple lines</div>
<div class="bottomRow">
<div class="cell c9 right last">Text</div>
<div class="cell c7 right gCol7">Text</div>
</div>
</div>
CSS
.gRow {
width:400px;
overflow: hidden;
position: relative;
border: 1px solid #d3d3d3;
padding-bottom: 20px;
}
.bottomRow {
position: absolute;
bottom: 0;
width: 100%;
}
.c7, .c8, .c9 {
width:80px
}
.right {
float: right;
}
.cell {
border-left: 1px solid red;
}

Resources