How to adapt div's width to content with flexbox - html

I want adapt the .flexrow div's width to content but i can't set it with flex.
HTML
<div class="fullwidth">
<div class="sidebar">
<p>sidebar</p>
<p>sidebar</p>
<p>sidebar</p>
<p>sidebar</p>
<p>sidebar</p>
<p>sidebar</p>
</div>
<div class="center">
<div class="flexrow">
<div class="card">
<p>card</p>
</div>
</div>
</div>
</div>
CSS
.center {
display: flex;
justify-content: center;
}
.flexrow {
display: inline-flex;
flex-direction: row;
flex-wrap: wrap;
}
.flexrow .card {
width: 300px;
height: 60px;
background-color: red;
margin: 10px;
padding: 10px;
text-align: center;
}
I have created a snippet here
This is an example of what i want:
Any suggestion?

The main problem here is that when an item wrap, whether one use Flexbox or not, its container won't adjust its width to the new content width.
With the existing markup, here is a simple fix in 2 steps to achieve that:
Add justify-content: center; to your .flexrow rule
For every possible column you need one less ghost element to push elements on the last row all the way to the left. The added elements together with new .flexrow .card:empty rule will do the magic.
.flexrow .card:empty {
height: 0;
margin: 0 10px;
padding: 0 10px;
}
Updated codepen
Stack snippet
.fullwidth {
background-color: grey;
display: flex;
}
.sidebar {
flex: 0 0 280px;
margin: 10px;
padding: 10px;
background-color: black;
color: white;
}
.flexrow {
display: flex;
flex-wrap: wrap;
align-content: center;
justify-content: center;
}
.flexrow .card {
width: 300px;
height: 60px;
background-color: red;
margin: 10px;
padding: 10px;
text-align: center;
}
.flexrow .card:empty {
height: 0;
margin: 0 10px;
padding: 0 10px;
}
<div class="fullwidth">
<div class="sidebar">
<p>sidebar</p>
<p>sidebar</p>
<p>sidebar</p>
<p>sidebar</p>
<p>sidebar</p>
<p>sidebar</p>
</div>
<div class="center">
<div class="flexrow">
<div class="card">
<p>card</p>
</div>
<div class="card">
<p>card</p>
</div>
<div class="card">
<p>card</p>
</div>
<div class="card">
<p>card</p>
</div>
<div class="card">
<p>card</p>
</div>
<div class="card">
<p>card</p>
</div>
<div class="card">
<p>card</p>
</div>
<!-- Ghost elements, if max columns is 4 one need 3 -->
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
</div>
</div>
</div>

Try this code-example
.flexrow .card {
height: 60px;
background-color: red;
margin: 10px;
padding: 10px;
text-align: center;
}
I removed the width, so that flexrow can adapt to the content.
Is this what you wanted? If not please specify (maybe a picture?)

UPDATE
Try this one:
.flexrow {
width: 90%;
display: inline-flex;
flex-direction: row;
flex-wrap: wrap;
-webkit-align-content: center;
align-content: center;
-webkit-justify-content: space-between;
justify-content: space-between;
margin: 0 auto;
}
.flexrow:after {
content: "";
width: 300px;
margin: 10px;
padding: 10px;
text-align: center;
}
Hope that what you're looking for :)

I guess what you want is that if you want the sidebar and the content to be side by side you need to use flex on the fullwidth div, check the code below:
.sidebar {
background: black;
color: white;
}
.fullwidth {
display: flex;
}
.center {
display: flex;
justify-content: center;
align-items:center;
width:100%;
}
.flexrow {
display: inline-flex;
flex-direction: row;
flex-wrap: wrap;
width:100%;
}
.flexrow .card {
width: calc(33.33% - 20px);
box-sizing:border-box;
height: 60px;
background-color: red;
margin: 10px;
padding: 10px;
text-align: center;
}
<div class="fullwidth">
<div class="sidebar">
<p>sidebar</p>
<p>sidebar</p>
<p>sidebar</p>
<p>sidebar</p>
<p>sidebar</p>
<p>sidebar</p>
</div>
<div class="center">
<div class="flexrow">
<div class="card">
<p>card</p>
</div>
<div class="card">
<p>card</p>
</div>
<div class="card">
<p>card</p>
</div>
<div class="card">
<p>card</p>
</div>
<div class="card">
<p>card</p>
</div>
<div class="card">
<p>card</p>
</div>
</div>
</div>
</div>

Related

column display using the flexbox

I am using the code where i have a bunch of divs, i want to show 4 columns per row and this is what i am using
.questions {
margin-bottom: 15px;
background: #e1e1e1;
display: flex;
padding: 30px;
gap: 30px;
align-items: top;
justify-content: left;
width: 100%;
flex-wrap: wrap;
.questions_divs {
display: flex;
flex-direction: column;
padding-left: 15px;
flex: 1 0 21%; /* explanation below */
}
here is the html
<div class="questions">
<div class="questions_div"></div>
<div class="questions_div"></div>
<div class="questions_div"></div>
<div class="questions_div"></div>
<div class="questions_div"></div>
<div class="questions_div"></div>
<div class="questions_div"></div>
<div class="questions_div"></div>
<div class="questions_div"></div>
<div class="questions_div"></div>
</div>
now when the lements are 3 or 3 or 6 or 9, i want them to come to next line, but they are coming in center and too much gap, how can i make sure they are left aligned with not too much gap
You mean something like this??
.questions {
margin-bottom: 15px;
background: #e1e1e1;
display: flex;
padding: 30px;
grid-gap: 30px;
align-items: top;
justify-content: left;
width: 100%;
flex-wrap: wrap;
}
.questions_div {
padding-left: 15px;
height:100px;
width:100px;
background-color:red;
flex: 1 0 1 21%;
}
<div class="questions">
<div class="questions_div">A</div>
<div class="questions_div">B</div>
<div class="questions_div">C</div>
<div class="questions_div">D</div>
<div class="questions_div">E</div>
<div class="questions_div">F</div>
<div class="questions_div">G</div>
<div class="questions_div">H</div>
<div class="questions_div">I</div>
<div class="questions_div">J</div>
</div>
Issues i found are listed below:
Close the bracket of .questions class in css.
.questions_divs - spelling mistake. It's .questions_div
flex: 1 0 21%; /* meaning - flex-grow flex-shrink flex-basis */
change flex: 1 0 21%; to flex: 0 0 25%; /for 4 columns in a row/
remove gap property. I am not sure but I think gap property is mostly used with grid css.
no need to add flex and flex direction to .questions_div. Add only if you want to handle the child elements inside .questions_div.
CSS-
* {
box-sizing: border-box;
}
.questions {
margin-bottom: 15px;
background: #e1e1e1;
display: flex;
padding: 30px;
/* gap: 30px; */
align-items: top;
justify-content: left;
width: 100%;
flex-wrap: wrap;
}
.questions_div {
/*display: flex;*/ /*no need to add this line*/
/*flex-direction: column;*/ /*no need to add this line*/
padding-left: 15px;
flex: 0 0 25%; /* flex-grow flex-shrink flex-basis */
}
HTML
<div class="questions">
<div class="questions_div">some text</div>
<div class="questions_div">some text</div>
<div class="questions_div">some text</div>
<div class="questions_div">some text</div>
<div class="questions_div">some text</div>
<div class="questions_div">some text</div>
<div class="questions_div">some text</div>
<div class="questions_div">some text</div>
<div class="questions_div">some text</div>
<div class="questions_div">some text</div>
</div>

Flex-direction for tables

Here is what I'm intending to do:
Table
Current HTML + CSS, for some reason the table can't contain multiple objects in a row.:
.boardTitle{
margin-top: 10px;
text-align: center;
font-size: 20px;
color: red;
}
.boardTable{
flex: 1;
flex-direction: column;
}
.boardRow{
flex-direction: row;
}
.thread{
border: solid;
}
<div>
<div class="boardTitle">
Name
</div>
<div class="boardTable">
<div class="boardRow">
<div class="thread">
1
</div>
<div class="thread">
2
</div>
</div>
</div>
</div>
class name .boardRow is the container which holds the threads, so you should give it a display property display: flex if you want them to be next each other.
.boardTitle{
margin-top: 10px;
text-align: center;
font-size: 20px;
color: red;
}
.boardTable{
flex: 1;
flex-direction: column;
}
.boardRow{
display:flex; <---- here
flex-direction: row;
}
.thread{
border: solid;
}
<div>
<div class="boardTitle">
Name
</div>
<div class="boardTable">
<div class="boardRow">
<div class="thread">
1
</div>
<div class="thread">
2
</div>
</div>
</div>
</div>

How to get nested css flex to have the right width after wrap in this setup?

I have this mockup, there are some nested containers. some of the link-class have multiple elements (par and ref) and I want them to display next to each other if there's space, but responsively move them below each other when total width gets smaller.
It works somewhat, but I expect (want) the link-element containing two childs to return to the same width as the link-element with one single child as it wraps.
For some reason, it remains wider than the single-child ones.
Any hints appreciated!
Code:
let name = 'world';
:global(body) {
margin: 0;
padding: 0
}
.main {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
background-color: gray;
}
.Container {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
background-color: lightblue;
padding: 3px
}
.linkContainer {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 3px;
background-color: salmon;
}
.par {
width: 80vw;
max-width: 300px;
background-color: red
}
.links {
display: flex;
flex-flow: row wrap;
padding: 3px;
background-color: orange
}
.ref {
background-color: olive;
width: 30vw;
max-width: 100px
}
.item {
width: 80vw;
max-width: 300px;
background-color: steelblue
}
<div class="main">
<div class="Container">
<div class="item">
header
</div>
<div class="linkContainer">
<div class="links">
<div class="par">
some text
</div>
</div>
<div class="links">
<div class="par">
some text
</div>
</div>
<div class="links">
<div class="par">
some text
</div>
</div>
<div class="Container">
<div class="item">
another header
</div>
<div class="linkContainer">
<div class="links">
<div class="par">
some text
</div>
<div class="ref">
a ref
</div>
</div>
<div class="links">
<div class="par">
some text
</div>
</div>
<div class="links">
<div class="par">
some text
</div>
<div class="ref">
a ref
</div>
</div>
</div>
</div>
</div>
</div>
</div>
you could simply add a max-width:300px; to .links and have the box in size but then you couldn't have the desired stacking effect you wanted so i went a bit further and with the help of css variables and media queries and adding a class .single to single .pars which didn't have a .ref after them, i came up with this:
:root {
--ref-size: 100px;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.main {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
background-color: gray;
}
.Container {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
background-color: lightblue;
padding: 3px
}
.links {
min-width: 300px;
display: flex;
flex-flow: row wrap;
padding: 3px;
background-color: orange;
}
.par {
width: calc(100% - var(--ref-size));
background-color: red;
}
.ref {
background-color: olive;
width: var(--ref-size);
}
.item {
width: 80vw;
max-width: 300px;
background-color: steelblue
}
#media all and (max-width:300px){
.par{
width: 100%;
}
}
#media all and (min-width: 300px){
.par.single{
width: 100%;
}
}
<div class="main">
<div class="Container">
<div class="item links">
header
</div>
<div class="links">
<div class="par single">
some text
</div>
</div>
<div class="links">
<div class="par single">
some text
</div>
</div>
<div class="links">
<div class="par single">
some text
</div>
</div>
<div class="item links">
another header
</div>
<div class="links">
<div class="par">
some text
</div>
<div class="ref">
a ref
</div>
</div>
<div class="links">
<div class="par single">
some text
</div>
</div>
<div class="links">
<div class="par">
some text
</div>
<div class="ref">
a ref
</div>
</div>
</div>
</div>

How can I get rows in table to align vertically when some rows have emojis and some rows do not?

I have an html page utilizing flex-box and a table which has text rows, in which some contain emojis and some do not. I have been unsuccessful thus far getting the rows to align vertically, such that all rows are centered vertically.
I have tried various combinations of margin and padding to no avail.
In the code provided you will see that rows without emojis are at the top and the ones with emojis are centered. If I make the rows without emojis centered, the rows with emojis are at the bottom. My goal is to have all rows properly centered vertically within the row under all cases.
.wrapper1 {
max-height: 200px;
margin-top: 50px;
margin-bottom: 15px;
padding-right: 25px;
padding-left: 25px;
}
.wrapper2 {
display: flex;
flex-direction: column;
flex-grow: 1;
}
.wrapper3 {
max-height:150px;
overflow: auto;
width: 100%;
}
.sm_table_header {
display:flex;
flex-direction: column;
border-top-left-radius:4px;
border-top-right-radius:4px;
color:#ffffff;
background-color: #307eab;
height: 20px;
}
.sm_table_row {
height: 25px;
display: flex; display: -webkit-flex;
flex-direction: row; -webkit-flex-direction: row;
flex-grow: 0; -webkit-flex-grow: 0;
flex-wrap: wrap; -webkit-flex-wrap: wrap;
width: 100%;
border-bottom: 1px solid silver;
border-collapse: collapse;
}
<div class="wrapper1">
<div class="wrapper2">
<div class="wrapper3">
<div class="sm_table_header ui-widget-header">
<div class="sm_table_row">
<div class="sm_table_subject_head">Subject</div>
</div>
</div>
</div>
<div class="wrapper3">
<div class="sm_table_body">
<div class="sm_table_row" id="1">
<div class="sm_table_subject">Test Emoji </div>
</div>
<div class="sm_table_row" id="1">
<div class="sm_table_subject">test 3</div>
</div>
<div class="sm_table_row" id="1">
<div class="sm_table_subject"><span class="span.emoji" style=">πŸ˜€</span>"Test Emoji 2 <span class="span.emoji">😎</span> - good deal</div>
</div>
<div class="sm_table_row" id="1">
<div class="sm_table_subject">Test Emoji 2 <span class="span.emoji">😎</span> - good deal</div>
</div>
</div>
</div>
You can simply set the line-height for .sm_table_row, will center each element perfectly.
.sm_table_row {
line-height: 25px;
}
.wrapper1 {
max-height: 200px;
margin-top: 50px;
margin-bottom: 15px;
padding-right: 25px;
padding-left: 25px;
}
.wrapper2 {
display: flex;
flex-direction: column;
flex-grow: 1;
}
.wrapper3 {
max-height:150px;
overflow: auto;
width: 100%;
}
.sm_table_header {
display:flex;
flex-direction: column;
border-top-left-radius:4px;
border-top-right-radius:4px;
color:#ffffff;
background-color: #307eab;
height: 20px;
}
.sm_table_row {
height: 25px;
display: flex; display: -webkit-flex;
flex-direction: row; -webkit-flex-direction: row;
flex-grow: 0; -webkit-flex-grow: 0;
flex-wrap: wrap; -webkit-flex-wrap: wrap;
width: 100%;
border-bottom: 1px solid silver;
border-collapse: collapse;
line-height: 25px;
}
<div class="wrapper1">
<div class="wrapper2">
<div class="wrapper3">
<div class="sm_table_header ui-widget-header">
<div class="sm_table_row">
<div class="sm_table_subject_head">Subject</div>
</div>
</div>
</div>
<div class="wrapper3">
<div class="sm_table_body">
<div class="sm_table_row" id="1">
<div class="sm_table_subject">Test Emoji </div>
</div>
<div class="sm_table_row" id="1">
<div class="sm_table_subject">test 3</div>
</div>
<div class="sm_table_row" id="1">
<div class="sm_table_subject"><span class="span.emoji" style=">πŸ˜€</span>"Test Emoji 2 <span class="span.emoji">😎</span> - good deal</div>
</div>
<div class="sm_table_row" id="1">
<div class="sm_table_subject">Test Emoji 2 <span class="span.emoji">😎</span> - good deal</div>
</div>
</div>
</div>
on .sm_table_row use
align-items: center;
"Flex items can be aligned in the cross axis of the current line of the flex container, similar to justify-content but in the perpendicular direction. align-items sets the default alignment for all of the flex container’s items, including anonymous flex items."
- flexbox cheatsheet: https://yoksel.github.io/flex-cheatsheet/#align-items
.wrapper1 {
max-height: 200px;
margin-top: 50px;
margin-bottom: 15px;
padding-right: 25px;
padding-left: 25px;
}
.wrapper2 {
display: flex;
flex-direction: column;
flex-grow: 1;
}
.wrapper3 {
max-height:150px;
overflow: auto;
width: 100%;
}
.sm_table_header {
display:flex;
flex-direction: column;
border-top-left-radius:4px;
border-top-right-radius:4px;
color:#ffffff;
background-color: #307eab;
height: 20px;
}
.sm_table_row {
height: 25px;
display: flex; display: -webkit-flex;
flex-direction: row; -webkit-flex-direction: row;
flex-grow: 0; -webkit-flex-grow: 0;
flex-wrap: wrap; -webkit-flex-wrap: wrap;
width: 100%;
align-items: center;
border-bottom: 1px solid silver;
border-collapse: collapse;
}
<meta charset="utf-8">
<div class="wrapper1">
<div class="wrapper2">
<div class="wrapper3">
<div class="sm_table_header ui-widget-header">
<div class="sm_table_row">
<div class="sm_table_subject_head">Subject</div>
</div>
</div>
</div>
<div class="wrapper3">
<div class="sm_table_body">
<div class="sm_table_row" id="1">
<div class="sm_table_subject">Test Emoji </div>
</div>
<div class="sm_table_row" id="1">
<div class="sm_table_subject">test 3</div>
</div>
<div class="sm_table_row" id="1">
<div class="sm_table_subject"><span class="span.emoji" style=">πŸ˜€</span>"Test Emoji 2 <span class="span.emoji">😎</span> - good deal</div>
</div>
<div class="sm_table_row" id="1">
<div class="sm_table_subject">Test Emoji 2 <span class="span.emoji">😎</span> - good deal</div>
</div>
</div>
</div>

Creating a layout with Flexbox

hey I'm new in Flexbox and I'm trying to get it as best as I can. However i faces a problem with some heights and orders, maybe some here could help out.
Note: Don't suggest using Grid/tables please.
this is what I have right now:
this is what I want to get:
html:
<div class="movie-container">
<div class="upper-container">
<div class="image">Image</div>
<div class="title">Title</div>
<div class="more">More</div>
</div>
<div class="lower-container">
<div class="runtime">Runtime</div>
<div class="description">Description</div>
<div class="director">Director</div>
</div>
</div>
css:
.movie-container{
display:flex;
flex-flow: column wrap;
}
.upper-container {
display: flex;
width:80%;
margin:0 auto;
flex-flow: raw wrap;
}
.upper-container div {
border: 1px solid black;
padding: 10px;
}
.lower-container {
display: flex;
width:80%;
margin:0 auto;
flex-flow: column wrap;
}
.lower-container div {
border: 1px solid black;
padding: 10px;
}
.image {
flex: 1;
}
.title {
flex: 3;
}
.more {
flex: 0.1;
}
.runtime{
}
.description{
}
.director{
}
Maybe other stuff need to be added beside flexbox I'm not sure, that's why I ask here. Any solution will be helpful!
If you change your HTML structure slightly you can accomplish this fairly easily:
<div class="movie-container">
<div class="upper-container">
<div class="image">Image</div>
<div class="side-container">
<div class="title">Title</div>
<div class="more">More</div>
<div class="runtime">Runtime</div>
<div class="description">Description</div>
</div>
</div>
<div class="lower-container">
<div class="director">Director</div>
</div>
</div>
JSFiddle
Flex isn't very good at stretching across multiple rows / columns like tables or Grid is, while you state you don't want that solution it is typically a better option in cases like this.
I find it easiest to work with flexbox on a row-by-row basis instead of using wrapping (although you can certainly do that too).
As a starting point, I think this snippet is what you're going for?
div {
flex: 1 1 auto;
}
.box {
border: 1px solid black;
}
.flex {
display: flex;
}
.image {
width: 120px;
flex: 0 0 auto;
}
.more {
flex: 0 0 auto;
}
<div class="flex upper">
<div class="box flex image">Image</div>
<div class="upper-detail">
<div class="flex title-container">
<div class="box title">Title</div>
<div class="box more">More</div>
</div>
<div class="box runetime">Runtime</div>
<div class="box director">Director</div>
</div>
</div>
<div class="box description">Description</div>
<div class="box other">Other stuff...</div>
Hope this helps.
.upper-container{
display: flex;
height: 200px;
}
.upper-left{
background: #ddd;
flex: 1;
display: flex;
align-items: center;
justify-content: center;
}
.upper-right{
flex: 3;
display: flex;
flex-direction: column;
height: 100%;
}
.title-more, .runtime, .director{
flex: 1;
border: 1px solid #222;
display: flex;
align-items: center;
}
.lower-container{
border: 1px solid #222;
padding: 10px;
}
.title-more{
justify-content: space-between;
}
.more-button{
height: 30px;
width: 100px;
border: 1px solid #333;
margin-right: 5px;
display: flex;
align-items: center;
justify-content: center;
}
<div class="movie-container">
<div class="upper-container">
<div class="upper-left">
Image
</div>
<div class="upper-right">
<div class="title-more">
<div class="title-container">
Title
</div>
<div class="more-button">
More
</div>
</div>
<div class="runtime">Runtime</div>
<div class="director">Director</div>
</div>
</div>
<div class="lower-container">
Description
</div>
</div>
The key is to add some divs and remove some others:
.movie-container *{padding:.5em;}
.upper-container {
display: flex;
padding:0;
}
.image {
border: 1px solid;
flex: 1 1 25%;
}
.tmrd{flex: 1 1 75%;padding:0}
.title-more {
display: flex;
padding:0;
}
.title{flex: 1 1 75%;border: 1px solid;}
.more{flex: 1 1 25%;border: 1px solid;}
.runtime,.description,.director{border: 1px solid;}
<div class="movie-container">
<div class="upper-container">
<div class="image">Image</div>
<div class="tmrd">
<div class="title-more">
<div class="title">Title</div>
<div class="more">More</div>
</div>
<div class="runtime">Runtime</div>
<div class="description">Description</div>
</div>
</div>
<div class="director">Director</div>
</div>