CSS display:flex equal parts - html

Can someone please tell me why the flexbox that I created isn't dividing the three child divs (image, content & action) into equal sizes vertically?
The plunk is here:
http://plnkr.co/edit/zqdpqnV7QkKrx7lm1Tsi?p=preview
CSS:
.card {
position: relative;
z-index: 2;
box-shadow: 0 0.1rem 0.2rem #aaa;
background: #fff;
border-radius: 0.2rem;
margin: 0.5rem 0 1rem 0;
height: 10rem;
display: flex;
flex-direction: column;
}
.card.sm {
height: 10rem;
}
.card.sm .card-action {
padding: 0.5rem;
}
.card.md {
height: 20rem;
}
.card.md .card-action {
padding: 1rem;
}
.card.lg {
height: 30rem;
}
.card.lg .card-action {
padding: 1.5rem;
}
.card .card-content {
padding: 1rem;
flex: 1 1 auto;
overflow-y: scroll;
}
.card .card-content .card-title {
font-weight: bold;
font-size: 1.1rem;
}
.card .card-action {
flex: 1 1 auto;
padding: 1rem;
border-top: 0.1rem solid rgba(160, 160, 160, 0.2);
text-transform: uppercase;
}
.card .card-image {
position: relative;
flex: 1 1 auto;
}
.card .card-image img {
border-radius: 2px 2px 0 0;
position: relative;
left: 0;
right: 0;
top: 0;
bottom: 0;
width: 100%;
}
HTML:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
</head>
<body>
<div style="width:30rem">
<div class="card md">
<div class="card-image">
<img src="http://images.freeimages.com/images/previews/8fe/sky-above-the-black-mountains-1402912.jpg"/>
</div>
<div class="card-content">
<span class="card-title">Title</span>
<p>Some content</p>
</div>
<div class="card-action">
This is a link
</div>
</div>
</div>
</body>
</html>

Because you are using flex-basis: auto instead of 0.
You may also need to use min-height: 0 or overflow different than visible to force same size even if the contents are taller.
.card > * {
flex: 1; /* Same height ... */
overflow: auto; /* ... even if the content is taller */
}
.card {
box-shadow: 0 0.1rem 0.2rem #aaa;
border-radius: 0.2rem;
margin: 0.5rem 0 1rem 0;
height: 20rem;
display: flex;
flex-direction: column;
}
.card > * {
flex: 1; /* Same height ... */
overflow: auto; /* ... even if the content is to tall */
}
.card.md .card-action {
padding: 1rem;
border-top: 0.1rem solid rgba(160, 160, 160, 0.2);
text-transform: uppercase;
}
.card .card-content {
padding: 1rem;
overflow-y: scroll;
font-weight: bold;
font-size: 1.1rem;
}
.card .card-image img {
border-radius: 2px 2px 0 0;
width: 100%;
}
<div style="width:30rem">
<div class="card md">
<div class="card-image">
<img src="http://images.freeimages.com/images/previews/8fe/sky-above-the-black-mountains-1402912.jpg"/>
</div>
<div class="card-content">
<span class="card-title">Title</span>
<p>Some content</p>
</div>
<div class="card-action">
This is a link
</div>
</div>
</div>
However, note that since you have paddings, the heights might still be a bit different. You may remove them and place them in an inner container instead. Or something like this:
.card > * {
flex: 1 2rem; /* Set flex-basis to the maximum paddings among flex items */
box-sizing: border-box;
}
.card {
box-shadow: 0 0.1rem 0.2rem #aaa;
border-radius: 0.2rem;
margin: 0.5rem 0 1rem 0;
height: 20rem;
display: flex;
flex-direction: column;
}
.card > * {
flex: 1 2rem;
overflow: auto;
box-sizing: border-box;
}
.card.md .card-action {
padding: 1rem;
border-top: 0.1rem solid rgba(160, 160, 160, 0.2);
text-transform: uppercase;
}
.card .card-content {
padding: 1rem;
overflow-y: scroll;
font-weight: bold;
font-size: 1.1rem;
}
.card .card-image img {
border-radius: 2px 2px 0 0;
width: 100%;
}
<div style="width:30rem">
<div class="card md">
<div class="card-image">
<img src="http://images.freeimages.com/images/previews/8fe/sky-above-the-black-mountains-1402912.jpg"/>
</div>
<div class="card-content">
<span class="card-title">Title</span>
<p>Some content</p>
</div>
<div class="card-action">
This is a link
</div>
</div>
</div>

.flex-container {
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
-webkit-flex-wrap: nowrap;
-ms-flex-wrap: nowrap;
flex-wrap: nowrap;
-webkit-justify-content: space-between;
-ms-flex-pack: justify;
justify-content: space-between;
-webkit-align-content: stretch;
-ms-flex-line-pack: stretch;
align-content: stretch;
-webkit-align-items: flex-start;
-ms-flex-align: start;
align-items: flex-start;
}
.flex-item:nth-child(1) {
-webkit-order: 0;
-ms-flex-order: 0;
order: 0;
-webkit-flex: 1 1 auto;
-ms-flex: 1 1 auto;
flex: 1 1 auto;
-webkit-align-self: auto;
-ms-flex-item-align: auto;
align-self: auto;
}
.flex-item:nth-child(2) {
-webkit-order: 0;
-ms-flex-order: 0;
order: 0;
-webkit-flex: 1 1 auto;
-ms-flex: 1 1 auto;
flex: 1 1 auto;
-webkit-align-self: auto;
-ms-flex-item-align: auto;
align-self: auto;
}
.flex-item:nth-child(3) {
-webkit-order: 0;
-ms-flex-order: 0;
order: 0;
-webkit-flex: 1 1 auto;
-ms-flex: 1 1 auto;
flex: 1 1 auto;
-webkit-align-self: auto;
-ms-flex-item-align: auto;
align-self: auto;
}

Related

CSS div position based on parent element

I struggle with an responsive attempt. I got two columns, where the width is based on VW. The bigger column contains am div element to close. This element should have always the same top and left margin, in relatives to the parent column. No matter if I resize the window.
Currently if I resize the distance between changes, either increase or shrinks to a point, where my close div get out of position c
body {
background: grey;
overflow: hidden;
}
.container-fluid {
width: 100%;
margin: auto;
display: flex;
flex-wrap: inherit;
align-items: center;
justify-content: space-between;
}
.col-lg-8 {
flex: 0 0 auto;
width: 66.666667%;
}
.col-lg-4 {
flex: 0 0 auto;
width: 33.333333%;
}
.card {
position: relative;
display: flex;
flex-direction: column;
height: 50vh;
background-color: #fff;
background-clip: border-box;
border: 0 solid rgba(0, 0, 0, 0.125);
border-radius: 1rem;
margin: 0.5em;
padding: 0.5em;
}
.title {
margin: 0.5em;
font-size: 3em;
float: left;
}
.close-btn {
position: absolute;
float: left;
cursor: pointer;
font-size: 2em;
left: 57vw;
top: 2vh;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>Fixed Close Position</title>
<!-- fontawesome stylesheet https://fontawesome.com/ -->
<script src="https://kit.fontawesome.com/98a5e27706.js" crossorigin="anonymous"></script>
</head>
<body>
<div class="container-fluid">
<div class="col-lg-8">
<div class="card">
<div class="title">Headline</div>
<div class="close-btn"><i class="fa-solid fa-circle-xmark"></i></div>
</div>
</div>
<div class="col-lg-4">
<div class="card">
<div class="title">News</div>
</div>
</div>
</div>
</body>
</html>
ompletely. I am stuck.
Try this,
body {
background: grey;
overflow: hidden;
}
.container-fluid {
width: 100%;
margin: auto;
display: flex;
flex-wrap: inherit;
align-items: center;
justify-content: space-between;
}
.col-lg-8 {
flex: 0 0 auto;
width: 66.666667%;
}
.col-lg-4 {
flex: 0 0 auto;
width: 33.333333%;
}
.card {
position: relative;
display: flex;
flex-direction: column;
height: 50vh;
background-color: #fff;
background-clip: border-box;
border: 0 solid rgba(0, 0, 0, 0.125);
border-radius: 1rem;
margin: 0.5em;
padding: 0.5em;
}
.title {
margin: 0.5em;
font-size: 3em;
float: left;
}
.close-btn {
position: absolute;
cursor: pointer;
font-size: 2em;
left: auto;
top: 2vh;
right: 2vh;
}

CSS : corner cut div , filled and border

I trying to create this two corner cut div, one is filled , another is border, both with shadow.
However I facing an issue, which is for border shape corner, I unable to create border with corner cut.
I appreciate with any other idea to create this kind of filled shape and border shape.
.buttongroup {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
.buttongroup .gap {
width: 30px;
-webkit-box-flex: 0;
-ms-flex: none;
flex: none;
}
.neonbutton {
display: -webkit-inline-box;
display: -ms-inline-flexbox;
display: inline-flex;
width: 100%;
position: relative;
}
.neonbutton .l {
width: 100%;
height: auto;
background-color: #37E8FC;
}
.neonbutton .r {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-align: start;
-ms-flex-align: start;
align-items: flex-start;
width: 30px;
-webkit-box-flex: 0;
-ms-flex: none;
flex: none;
}
.neonbutton .corner {
width: 0;
height: 0;
border-style: solid;
border-width: 25px 0 0 30px;
border-color: transparent transparent transparent #37E8FC;
}
.neonbutton .square {
height: 30px;
width: 30px;
background-color: #37E8FC;
}
.neonbutton .value {
position: absolute;
width: 100%;
height: 100%;
text-align: center;
color: #000;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
font-size: 17px;
font-weight: bold;
}
.neonbutton.outline .l {
background-color: transparent;
border: 2px solid #37E8FC;
border-right: none;
}
.neonbutton.outline .corner {
background-color: transparent;
}
.neonbutton.outline .square {
background-color: transparent;
border-right: 2px solid #37E8FC;
border-bottom: 2px solid #37E8FC;
}
<div class="buttongroup">
<div class="neonbutton">
<div class="l"></div>
<div class="r">
<div class="corner"></div>
<div class="square"></div>
</div>
<div class="value">Lorem</div>
</div>
<div class="gap"></div>
<div class="neonbutton outline">
<div class="l"></div>
<div class="r">
<div class="corner"></div>
<div class="line"></div>
<div class="square"></div>
</div>
<div class="value">Lorem</div>
</div>
</div>
I would do the first one like below:
.box {
--c:20px; /* control the cut */
font-size: 25px;
padding: 10px 30px;
display: inline-block;
position: relative;
z-index: 0;
filter: drop-shadow(0 0 5px #37E8FC)
}
.box:before {
content: "";
position: absolute;
z-index: -1;
inset: 0;
background: #37E8FC;
clip-path: polygon(0 0, calc(100% - var(--c)) 0, 100% var(--c), 100% 100%, 0 100%);
}
body {
background: #000;
}
<div class="box">some text</div>
And the second one:
.box {
--b:5px; /* control the border */
--c:20px; /* control the cut */
font-size: 25px;
padding: 10px 30px;
display: inline-block;
position: relative;
color:#fff;
z-index: 0;
filter: drop-shadow(0 0 5px #37E8FC)
}
.box:before {
content: "";
position: absolute;
z-index: -1;
inset: 0;
background: linear-gradient(to bottom left, #37E8FC 50%,#0000 50.5%) 100% 0/calc(var(--c) - 0.3*var(--b)) calc(var(--c) - 0.3*var(--b)) no-repeat;
border:var(--b) solid #37E8FC;
clip-path: polygon(0 0, calc(100% - var(--c)) 0, 100% var(--c), 100% 100%, 0 100%);
}
body {
background: #000;
}
<div class="box">some text</div>

Z-index not applying on :hover for flex elements

I have two side by side divs. The right div is set to expand on hover and display a message. I have set the z-index on the expanding div to be z-index: 1 and the left div and all its children to be z-index: 0, however the expanding div will only expand as far as the text in the div beside it.
I have read multiple questions here about z-index and flex items but can't work out what I am doing wrong. I have added a higher z-index to my first flex-item as described here Z-index doesn't work with flex elements? but that has not fixed it.
.container {
display: flex;
background-color: lightgray;
height: 48px;
width: 139px;
border-radius: 4px;
}
.container .inner {
height: 48px;
}
.container .inner > div {
display: flex;
z-index: 0;
}
.container .inner.left {
display: flex;
flex-direction: column;
flex: 1 0 auto;
padding-left: 10px;
justify-content: center;
}
.container .inner.right {
display: flex;
flex: 0 1 8px;
background-color: red;
border-radius: 0 4px 4px 0;
overflow: hidden;
transition: 0.3s;
cursor: pointer;
z-index: 1;
}
.container .inner.right .info-msg {
display: none;
transition: 0.3s;
}
.container .inner.right:hover {
flex: 0 1 150px;
}
.container .inner.right:hover .info-msg {
display: flex;
}
<div class="container">
<div class="inner left">
<div class="time">9:00am - 5:00pm</div>
<div class="name">Worker</div>
</div>
<div class="inner right">
<div class="info-msg">Message</div>
</div>
</div>
Z-Index is not the issue here. You can set the position to absolute so the right div goes over the left on hover.
This code works:
.container {
height: 48px;
width: 139px;
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
background-color: lightgray;
border-radius: 4px;
}
.inner {
padding-left: 10px;
}
.right {
height: 48px;
width: 8px;
position: absolute;
right: 0px;
display: flex;
align-items: center;
background-color: red;
border-radius: 0 4px 4px 0;
transition: 0.7s;
cursor: pointer;
}
.right:hover {
width: 129px;
border-radius: 4px;
}
.info-msg {
overflow: hidden;
}
This is not a z-index issue. It is a width issue. When the element expands the other element still occupies part of the width and therefore the expanding element stops.
You can add flex-shrink: 1 to the left element for the effect to take place. Also, you can set different position. Or you can use transform: translateX(-100%).
.container {
display: flex;
background-color: lightgray;
height: 48px;
width: 139px;
border-radius: 4px;
}
.container .inner {
height: 48px;
}
.container .inner>div {
display: flex;
z-index: 0;
}
.container .inner.left {
display: flex;
flex-direction: column;
flex: 1 0 auto;
padding-left: 10px;
justify-content: center;
/* Add flex shrink */
flex-shrink: 1;
}
.container .inner.right {
display: flex;
flex: 0 1 8px;
background-color: red;
border-radius: 0 4px 4px 0;
overflow: hidden;
transition: 0.3s;
cursor: pointer;
z-index: 1;
}
.container .inner.right .info-msg {
display: none;
transition: 0.3s;
}
.container .inner.right:hover {
flex: 0 1 150px;
}
.container .inner.right:hover .info-msg {
display: flex;
}
<div class="container">
<div class="inner left">
<div class="time">9:00am - 5:00pm</div>
<div class="name">Worker</div>
</div>
<div class="inner right">
<div class="info-msg">Message</div>
</div>
</div>
As mentioned in the comments above, you can make inner right div position: absolute with parent div position relative.
Check the snippet:
.container {
display: flex;
background-color: lightgray;
height: 48px;
width: 139px;
border-radius: 4px;
position: relative;
}
.container .inner {
height: 48px;
}
.container .inner > div {
display: flex;
z-index: 0;
}
.container .inner.left {
display: flex;
flex-direction: column;
flex: 1 0 auto;
padding-left: 10px;
justify-content: center;
}
.container .inner.right {
display: flex;
background-color: red;
border-radius: 0 4px 4px 0;
overflow: hidden;
transition: 0.3s;
cursor: pointer;
z-index: 1;
position: absolute;
right: 0;
top: 0;
bottom: 0;
left: calc(100% - 8px);
width: 8px;
padding: 5px;
box-sizing: border-box;
}
.container .inner.right .info-msg {
display: none;
transition: 0.3s;
}
.container .inner.right:hover {
left: 0;
width: 100%;
border-radius: 4px;
}
.container .inner.right:hover .info-msg {
display: flex;
}
<div class="container">
<div class="inner left">
<div class="time">9:00am - 5:00pm</div>
<div class="name">Worker</div>
</div>
<div class="inner right">
<div class="info-msg">Message</div>
</div>
</div>

Responsive height layout with dynamic height elements

I am trying to build a layout with a menubar and a main container that includes a searchbar, left sidebar, and a results table.
I want the main container to always be as tall as possible for the window and the left sidebar and results table to also be as tall as possible within the main container.
This is how this would look with fixed heights on everything:
https://jsfiddle.net/m45cakne/1/
<div class="menubar"></div>
<div class="main-section">
<div class="searchbar">
</div>
<div class="section-content">
<div class="sidebar"></div>
<div class="results-table"></div>
</div>
</div>
* {
box-sizing: border-box;
}
html, body {
height: 100%;
}
.menubar {
height: 50px;
border: 1px solid black;
}
.main-section {
border: 1px solid black;
margin-top: 20px;
height: 600px;
}
.searchbar {
border: 1px solid black;
margin: 20px;
height: 50px;
}
.section-content {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
padding-right: 25px;
padding-left: 25px;
flex: 1;
}
.sidebar {
-webkit-box-flex: 0;
-ms-flex: 0 0 25%;
flex: 0 0 25%;
max-width: 25%;
border: 1px solid black;
position: relative;
width: 100%;
min-height: 1px;
padding-right: 15px;
padding-left: 15px;
height: 490px;
}
.results-table {
-webkit-box-flex: 0;
-ms-flex: 0 0 75%;
flex: 0 0 75%;
max-width: 75%;
position: relative;
width: 100%;
min-height: 1px;
border: 1px solid black;
height: 490px;
padding: 0px;
}
The menubar height can change as the page is viewed on different devices, and the searchbar height can also change as it is filled with search terms.
What would be the right method to build this responsive layout with CSS?
Just use flex properties all the way through:
body {
display: flex;
flex-direction: column;
height: 100vh;
margin: 0;
}
.menubar {
flex: 0 0 50px;
border: 1px solid black;
}
.main-section {
flex: 1;
display: flex;
flex-direction: column;
border: 1px solid black;
margin-top: 20px;
padding: 25px;
}
.searchbar {
flex: 0 0 50px;
margin-bottom: 20px;
border: 1px solid black;
}
.section-content {
flex: 1;
display: flex;
flex-wrap: wrap;
}
.sidebar {
flex: 0 0 25%;
border: 1px solid black;
}
.results-table {
flex: 1;
border: 1px solid black;
}
* {
box-sizing: border-box;
}
<div class="menubar">menu bar</div>
<div class="main-section">main container
<div class="searchbar">search bar</div>
<div class="section-content">
<div class="sidebar">side bar</div>
<div class="results-table">results table</div>
</div>
</div>
jsFiddle demo

Why `Box-shadow` Is not displayed at the bottom in IE11?

I added box-shadow using pseudo selector to a display: flex; flex-flow: row wrap; element it's working in chrome and safari but in IE11 it get floats to the right side not the bottom, I think its because of flex-flow: row wrap;. any thoughts on whats goin on?
.main {
max-width: 1200px;
overflow: hidden;
height: 600px;
}
img {
display: block;
}
.hero-image {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-flow: row wrap;
flex-flow: row wrap;
width: 100%;
position: relative;
}
.hero-image::after {
display: block;
position: absolute;
content: '';
width: 100%;
-webkit-box-shadow: 0 -5px 50px #000;
box-shadow: 0 -5px 50px #000;
height: 100%;
z-index: 99;
}
.div--1 {
flex-basis: 100%;
order: 1;
height: auto;
}
.div--2 {
background-color: #333d47;
padding: 10px 40px;
line-height: 1;
flex-basis: 100%;
text-align: center;
color: #FFF;
order: -1;
}
<div class="main">
<div class="hero-image">
<div class="div--1">
<img src="https://picsum.photos/1200/300?image=0" />
</div>
<div class="div--2">some text here</div>
</div>
</div>
You are just missing a top: 0; on .hero-image::after. Otherwise the shadow will be pulled down by the text and the image.
.main {
max-width: 1200px;
overflow: hidden;
height: 600px;
}
img {
display: block;
}
.hero-image {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-flow: row wrap;
flex-flow: row wrap;
width: 100%;
position: relative;
}
.hero-image::after {
display: block;
position: absolute;
top: 0;
content: '';
width: 100%;
-webkit-box-shadow: 0 -5px 50px #000;
box-shadow: 0 -5px 50px #000;
height: 100%;
z-index: 99;
}
.div--1 {
flex-basis: 100%;
order: 1;
height: auto;
}
.div--2 {
background-color: #333d47;
padding: 10px 40px;
line-height: 1;
flex-basis: 100%;
text-align: center;
color: #FFF;
order: -1;
}
<div class="main">
<div class="hero-image">
<div class="div--1">
<img src="https://picsum.photos/1200/300?image=0" />
</div>
<div class="div--2">some text here</div>
</div>
</div>
The shadow is over the image:
.main {
max-width: 1200px;
overflow: hidden;
height: 600px;
}
img {
display: block;
}
.hero-image {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-flow: row wrap;
flex-flow: row wrap;
width: 100%;
position: relative;
}
.div--1::after {
display: block;
position: relative;
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, rgba(0, 0, 0, 0)), to(#000));
background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0, #000 100%);
margin-top: -120px;
height: 120px;
width: 100%;
content: '';
}
.div--1 {
flex-basis: 100%;
order: 1;
height: auto;
}
.div--2 {
background-color: #333d47;
padding: 10px 40px;
line-height: 1;
flex-basis: 100%;
text-align: center;
color: #FFF;
order: -1;
}
<div class="main">
<div class="hero-image">
<div class="div--1">
<img src="https://picsum.photos/1200/300?image=0" />
</div>
<div class="div--2">some text here</div>
</div>
</div>