Distribute row contents based on avaiable height - html

I want my .info class fit with the available height and each of the 3 rows taking 33% of that height. here is my code.
div {
display: block;
}
.content {
box-sizing: border-box;
display: flex;
align-items: center;
width: 310px;
position: relative;
border: .09rem solid rgb(36, 41, 46);
border-radius: .3rem;
}
.avatar {
text-align: center;
position: relative;
width: 30%
}
.avatar img {
min-height: 150px;
min-width: 150px;
border: .09rem solid rgb(36, 41, 46);
}
.info {
width: 70%;
margin-right: .1rem;
text-align: right;
}
<body>
<div class="content">
<div class="avatar">
<img src="http://notavaiable.com" alt="not">
</div>
<div class="info">
<div class="row">
<span>name</span>
</div>
<div class="row">
<span>17</span>
<span>20</span>
<span>1</span>
</div>
<div class="row">location</div>
</div>
</div>
</body>
Please Help me. Thanks in advance.

I had to change your css a little. Namely:
Assign align-items: stretch to .content;
Assign min-height: 150px and min-width: 100% to .avatar img;
Assign display: flex and flex-direction: column to .info;
And make a replacement for this selector:
div {
display: block;
}
To this selector:
.info .row {
flex: 1;
}
This rule sets the height of 1/3 to each .row.
.content {
box-sizing: border-box;
display: flex;
align-items: stretch;
width: 310px;
position: relative;
border: .09rem solid rgb(36, 41, 46);
border-radius: .3rem;
}
.avatar {
text-align: center;
position: relative;
width: 30%;
}
.avatar img {
min-height: 150px;
min-width: 100%;
border: .09rem solid rgb(36, 41, 46);
}
.info {
width: 70%;
margin-right: .1rem;
text-align: right;
display: flex;
flex-direction: column;
}
.info .row {
flex: 1;
}
<body>
<div class="content">
<div class="avatar">
<img src="http://notavaiable.com" alt="not">
</div>
<div class="info">
<div class="row">
<span>name</span>
</div>
<div class="row">
<span>17</span>
<span>20</span>
<span>1</span>
</div>
<div class="row">location</div>
</div>
</div>
</body>

here is your code if I understood correctly
.content {
display: flex;
width: 310px;
border: 1px solid rgb(36, 41, 46);
border-radius: 0.3rem;
box-sizing: border-box;
}
.avatar {
width: 30%;
}
.avatar img {
height: 100%;
width: 100%;
border: 1px solid rgb(36, 41, 46);
box-sizing: border-box;
flex-shrink: 0;
}
.info {
width: 70%;
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: stretch;
}
.row {
flex: 1
}
<div class="content">
<div class="avatar">
<img src="https://picsum.photos/150/150" alt="not">
</div>
<div class="info">
<div class="row">
<span>name</span>
</div>
<div class="row">
<span>17</span>
<span>20</span>
<span>1</span>
</div>
<div class="row">location</div>
</div>
</div>

Related

How do I divide blocks in my page with flexbox?

I'm facing this problem where I want to have a header, sidebar and content with flexbox. I can't get to a solution to divide these 3 childs. I've been trying to use flex-grow and flex-direction:row but I'm having a problem.
Image of the website
How I want it to be
<style>
.parent {
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
height: 100vh;
border: 20px solid black;
display: flex;
flex-direction: column;
}
.header {
width: 200px;
height: 200px;
background: cornflowerblue;
}
.side {
width: 200px;
height: 200px;
background: rgb(219, 133, 133);
}
.content {
width: 200px;
height: 200px;
background: rgb(115, 202, 180);
}
.text {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
height: 190px;
color: #fff;
}
</style>
<div class="parent">
<div class="header">
<h2 class="text">Header</h2>
</div>
<div class="side">
<h2 class="text">Side</h2>
</div>
<div class="content">
<h2 class="text">Content</h2>
</div>
</div>
You need to create two containers, one for all your elements and one for your header and content.
<div class="parent"> <!-- Container 1 -->
<div class="side">
<h2 class="text">Side</h2>
</div>
<div class="container"> <!-- Container 2 -->
<div class="header">
<h2 class="text">Header</h2>
</div>
<div class="content">
<h2 class="text">Content</h2>
</div>
</div>
</div>
Then, you can treat each container as a separate flex-box. the parent will have a flex-direction: row; and the container will have flex-direction: column;.
You also want to set values in percentages, not absolute values as you have right now (200px, 20rem..).
.parent {
box-sizing: border-box;
margin: 0;
padding: 0;
height: 100vh;
border: 20px solid black;
display: flex;
flex-direction: row;
}
.header {
height: 30%;
background: cornflowerblue;
}
.side {
width: 30%;
height: 100%;
background: rgb(219, 133, 133);
}
.content {
height: 70%;
background: rgb(115, 202, 180);
}
.text {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
height: 190px;
color: #fff;
}
.container {
display: flex;
flex-direction: column;
width: 70%;
height: 100%;
}
JSFiddle
Images to illustrate the separation:
You have to wrap your header & content section inside another div. Something like this below example. However, The best way to achieve this layout is using a CSS grid. Here is the complete CSS grid guide
.parent {
display: flex;
height: 100vh;
background: #000;
padding: 5px;
margin: 0;
}
.side {
border: 1px solid #000;
width: 30vw;
display: flex;
justify-content: center;
align-items: center;
background: #fff;
margin-right: 5px;
}
.main-body {
border: 1px solid #000;
width: 70vw;
}
.header,
.content {
display: flex;
justify-content: center;
background: #fff;
}
.header {
height: 25vh;
margin-bottom: 5px;
}
.content {
align-items:center;
height: 70vh;
}
<div class="parent">
<div class="side">
<h2 class="text">Side</h2>
</div>
<div class="main-body">
<div class="header">
<h2 class="text">Header</h2>
</div>
<div class="content">
<h2 class="text">Content</h2>
</div>
</div>
</div>
I don't think that you deeply understand how flexbox work. You should read more about it. I advice you to read a book called CSS-in Depth. You can download it online from a website called Z-lib. Try to understand the code that I posted for you.
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.parent {
height: 100vh;
border: 20px solid black;
display: flex;
background: pink;
}
.main {
display: flex;
backgound-color: green;
flex-direction: column;
flex: 2
}
.header {
background: cornflowerblue;
}
.side {
flex: 1;
background: rgb(219, 133, 133);
}
.content {
background: rgb(115, 202, 180);
flex: 1
}
.text {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
height: 190px;
color: #fff;
}
</style>
<div class="parent">
<div class="side">
<h2 class="text">Side</h2>
</div>
<div class="main">
<div class="header">
<h2 class="text">Header</h2>
</div>
<div class="content">
<h2 class="text">Content</h2>
</div>
</div>
</div>

Align circles and text made with css

I made this layout but I can't find a way to align the circles and the text on the same line. As you can see in the first picture there's a problem both with circles and text. I'd like to achive the result you see in the 2nd picture.
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.grid {
display: flex;
flex-wrap: wrap;
max-width: 980px;
width: 100%;
margin: auto;
padding-top: 5%;
padding-bottom: 5%;
}
.cell {
flex-basis: 33.3%;
display: flex;
justify-content: center;
align-items: center;
}
.cell:before {
padding-bottom: 100%;
display: block;
content: '';
}
.circle {
width: 250px;
height: 250px;
border: 0.5px solid;
border-radius: 50%;
background-position: center;
background-size: contain;
background-repeat: no-repeat;
box-shadow: 0px 0px 15px 0px;
overflow: hidden;
margin: 0 auto 1em;
}
.circle img {
width: 100%;
position: relative;
height: 100%;
}
h3 {
text-align: center;
}
.inner {
text-align: start;
padding-bottom: 15%;
}
<div class="grid">
<div class="cell">
<div class="inner">
<div class="circle" style="background-image:url('https://freight.cargo.site/t/original/i/655f74e74d3b88cc9d367ba8cccd79680c3837a84a547f9e03b6f39981f424e0/3.png');"></div>
<div class="caption">
<h3>Chiara Bersani <br> Marta Montanini</h3>
</div>
</div>
</div>
First, you will have to remove your manual line breaks <br>. Once you do this, the text can wrap automatically without having odd breaks at specific breaking points. If you want to force a line break, use horizontal padding on .caption h3.
Once you do this, just use align-items: self-start; on .grid.
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.grid {
display: flex;
flex-wrap: wrap;
align-items: self-start;
max-width: 980px;
width: 100%;
margin: auto;
padding-top: 5%;
padding-bottom: 5%;
}
.cell {
flex-basis: 33.3%;
display: flex;
justify-content: center;
align-items: center;
}
.cell:before {
padding-bottom: 100%;
display: block;
content: '';
}
.circle {
width: 250px;
height: 250px;
border: 0.5px solid;
border-radius: 50%;
background-position: center;
background-size: contain;
background-repeat: no-repeat;
box-shadow: 0px 0px 15px 0px;
overflow: hidden;
margin: 0 auto 1em;
}
.circle img {
width: 100%;
position: relative;
height: 100%;
}
.caption h3 {
text-align: center;
padding: 0 2em;
}
.inner {
text-align: start;
padding-bottom: 15%;
}
<div class="grid">
<div class="cell">
<div class="inner">
<div class="circle" style="background-image:url('https://freight.cargo.site/t/original/i/655f74e74d3b88cc9d367ba8cccd79680c3837a84a547f9e03b6f39981f424e0/3.png');"></div>
<div class="caption">
<h3>Chiara Bersani Marta Montanini</h3>
</div>
</div>
</div>
<div class="cell">
<div class="inner">
<div class="circle" style="background-image:url('https://freight.cargo.site/t/original/i/655f74e74d3b88cc9d367ba8cccd79680c3837a84a547f9e03b6f39981f424e0/3.png');"></div>
<div class="caption">
<h3>Chiara Bersani Longer TEXT...........................</h3>
</div>
</div>
</div>
<div class="cell">
<div class="inner">
<div class="circle" style="background-image:url('https://freight.cargo.site/t/original/i/655f74e74d3b88cc9d367ba8cccd79680c3837a84a547f9e03b6f39981f424e0/3.png');"></div>
<div class="caption">
<h3>Chiara Bersani Marta Montanini more text lorem foo</h3>
</div>
</div>
</div>
</div>

Top of scrollable div not visible

I need to add a vertically scrollable div in my project. The div is a list of items with fixed height. I can't figure out why the top area of the div is not visible. Below is some sample code. As you can see, the first element of the list is not entirely visible.
html,
body {
height: 100%;
}
* {
box-sizing: border-box;
}
.main-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
background-image: linear-gradient(45deg, #85ffbd 0%, #fffb7d 100%);
}
.content {
width: 75%;
max-height: 500px;
background-color: white;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.post-list {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: rgba(0, 0, 0, 0.03);
width: 95%;
border-radius: 5px;
overflow-y: scroll;
overflow-x: hidden;
position: relative;
}
.post-item {
border: 1px solid black;
width: 100%;
margin: 0.5rem;
}
.test {
height: 8rem;
background-color: rgba(255, 0, 0, 0.1);
width: 100%;
text-align: center;
}
<div class="main-container">
<div class="content">
<h1>Some list</h1>
<div class="post-list">
<div class="post-item"> <div class="test"> 1. some content </div> </div>
<div class="post-item"> <div class="test"> 2. some content </div> </div>
<div class="post-item"> <div class="test"> 3. some content </div> </div>
<div class="post-item"> <div class="test"> 4. some content </div> </div>
</div>
</div>
</div>
https://jsfiddle.net/1dphx94s/8/
Just remove justify-content: center in post-list it places all the content in the center of div and makes huge struggling which is not necessary in our case, you just need to center elements on X-axis, flex and align-items are enough
html,
body {
height: 100%;
}
* {
box-sizing: border-box;
}
.main-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
background-image: linear-gradient(45deg, #85ffbd 0%, #fffb7d 100%);
}
.content {
width: 75%;
max-height: 500px;
background-color: white;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.post-list {
display: flex;
flex-direction: column;
align-items: center;
/*justify-content: center;*/
background-color: rgba(0, 0, 0, 0.03);
width: 95%;
border-radius: 5px;
overflow-y: scroll;
overflow-x: hidden;
position: relative;
}
.post-item {
border: 1px solid black;
width: 100%;
margin: 0.5rem;
}
.test {
height: 8rem;
background-color: rgba(255, 0, 0, 0.1);
width: 100%;
text-align: center;
}
<div class="main-container">
<div class="content">
<h1>Some list</h1>
<div class="post-list">
<div class="post-item"> <div class="test"> 1. some content </div> </div>
<div class="post-item"> <div class="test"> 2. some content </div> </div>
<div class="post-item"> <div class="test"> 3. some content </div> </div>
<div class="post-item"> <div class="test"> 4. some content </div> </div>
</div>
</div>
</div>

Make the parent div width the same as the children

I made this layout that seems to work, the only problem is that I would like that all che filled div are centered.
There are three possible "states":
the cyan element is to the left of all the others
the gold and pink elements are on two columns
all elements are on a single column.
What I want:
In the first case, everything is centered and it works, in the other two it doesn't: the elements are always aligned to the left.
To center I was thinking of using margin: 0 auto but it seems the divs are bigger than their content even if I used inline-flex (look at the grey area during state #3 in the running example). Why?
How can I solve?
.container {
outline: 1px solid black;
max-width: 490px;
margin: 0 auto;
}
.columns {
outline: 1px solid black;
display: inline-flex;
flex-wrap: wrap;
}
.map {
background-color: cyan;
width: 150px;
min-width: 150px;
height: 150px;
min-height: 150px;
margin-right: 20px;
}
.content {
outline: 1px solid black;
background-color: lightgray;
max-width: 320px;
}
.cards {
outline: 1px solid black;
display: inline-flex;
flex-wrap: wrap;
}
.card {
background-color: pink;
outline: 1px solid black;
width: 150px;
height: 70px;
display: inline-block;
}
.card.left {
margin-right: 20px;
}
.texts {
outline: 1px solid black;
display: inline-flex;
flex-wrap: wrap;
}
.text {
background-color: gold;
outline: 1px solid black;
width: 150px;
height: 200px;
display: inline-block;
}
.text.left {
margin-right: 20px;
}
<div class="container">
<div class="columns">
<div class="map"></div>
<div class="content">
<div class="cards">
<div class="card left">card #1</div>
<div class="card">card #2</div>
<div class="card left">card #3</div>
<div class="card">card #4</div>
</div>
<div class="texts">
<div class="text left">text #1</div>
<div class="text">text #2</div>
</div>
</div>
</div>
</div>
use media queries in the proper way and here you go, to play with it find this fiddle link, try to resize the result window.
.container {
max-width: 490px;
margin: 0 auto;
}
.columns {
display: inline-flex;
flex-wrap: wrap;
}
.map {
background-color: cyan;
width: 150px;
min-width: 150px;
height: 150px;
min-height: 150px;
margin-right: 20px;
}
.content {
background-color: lightgray;
max-width: 320px;
}
.cards {
display: inline-flex;
flex-wrap: wrap;
}
.card {
background-color: pink;
width: 150px;
height: 70px;
display: inline-block;
}
.card.left {
margin-right: 20px;
}
.texts {
display: inline-flex;
flex-wrap: wrap;
}
.text {
background-color: gold;
width: 150px;
height: 200px;
display: inline-block;
}
.text.left {
margin-right: 20px;
}
#media(max-width: 520px){
.container {
display: flex;
flex-direction: column;
align-items: center;
}
.columns {
display: inline-block;
}
}
#media(max-width: 352px){
.container {
display: flex;
flex-direction: column;
align-items: center;
}
.map {margin-right: 0;}
.content {
max-width: min-content;
}
.card.left {
margin-right: 0px;
}
.text.left {
margin-right: 0px;
}
}
<div class="container">
<div class="columns">
<div class="map"></div>
<div class="content">
<div class="cards">
<div class="card left">card #1</div>
<div class="card">card #2</div>
<div class="card left">card #3</div>
<div class="card">card #4</div>
</div>
<div class="texts">
<div class="text left">text #1</div>
<div class="text">text #2</div>
</div>
</div>
</div>
</div>

Dispay flex row and uniformed sizes

I would like all my element to have the same height and the separator to cover all the height. How can I achieve that please ?
The separator is pink, you can see it here with a height: 5em
.daddy {
height: 10em;
width: 10em;
}
.container {
width: auto;
height: auto;
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: center;
border: 1px solid lightgrey;
}
.child1 {
width: 3em;
height: 10em;
background-color: red;
}
.child2 {
width: 3em;
height: 15em;
background-color: blue;
}
.separator {
width: 10px;
height: 5em;
background-color: pink;
}
<div class="daddy">
<div class="container">
<div class="child1"></div>
<div class="separator"></div>
<div class="child2"></div>
</div>
</div>
If you remove the align items from container, all three columns will grow to fill the row
.daddy {
height: 10em;
width: 10em;
}
.container {
width: auto;
height: auto;
display: flex;
flex-direction: row;
border: 1px solid lightgrey;
justify-content:center;
}
.child1 {
width: 3em;
background-color: red;
height: 10em; /* this is just to give it some height as no column currently has any height */
}
.child2 {
width: 3em;
background-color: blue;
}
.separator {
width: 10px;
background-color: pink;
}
<div class="daddy">
<div class="container">
<div class="child1">
</div>
<div class="separator">
</div>
<div class="child2">
</div>
</div>
</div>