Center-align one element while right-aligning its only sibling using flexbox - html

I am trying to achieve this using flexbox:
I know how to do it by using a hidden element as in this fiddle:
.container {
display: flex;
justify-content: space-between;
border: 3px solid blue;
}
.box {
width: 100px;
height: 100px;
background: red;
}
.box:first-child {
visibility: hidden;
}
<div class="container">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
But this seems like too hacky to be right.

Use the flex property that sets the flexible length on flexible items. That way, I'm telling the white-box to take all available space but the first white-box will be 50% larger than the normal white -box, that will take the place of what's left
.container {
display: flex;
border: 3px solid blue;
}
.box {
width: 100px;
height: 100px;
background: red;
}
.white-box {
background: white;
flex: 1;
}
.white-box:first-child {
flex: 1.5
}
<div class="container">
<div class="white-box"></div>
<div class="box"></div>
<div class="white-box"></div>
<div class="box"></div>
</div>

you can easily achieve this kind of layout by using CSS grid
.grid-container {
display: grid;
grid-template-columns: auto 100px 200px 100px;
border: 1px solid blue;
}
.grid-container > div {
text-align: center;
font-size: 30px;
padding: 20px 0px;
}
.red{
background-color: red;
}
<div class="grid-container">
<div>1</div>
<div class="red">2</div>
<div>3</div>
<div class="red">4</div>
</div>
Hope this will be helpful for you

you need to remove
.box:first-child {
visibility: hidden;
}

Related

CSS Display: inline-block but Stack Divs only if they overlap

I have the following divs below:
.parent {
padding: 10px;
background: grey;
}
.child {
background: green;
display: block;
position: relative;
width: 50px;
}
.stacked {
left: 0px;
}
.three {
left: 200px;
}
<div class="parent">
<div class="child stacked">div1</div>
<div class="child stacked">div2</div>
<div class="child three">div3</div>
</div>
This looks like the following:
I would like divs 1 and 2 to stack as they do, but since div3 does not collide with the divs above, I'd like it to vertically aline with div 1.
If I switch display to inline or inline-block, it pushes div 2 to the right of div one. and the left values are not accurate to the parant.
The left values of the divs will be dynamically generated so I cannot know if the divs are overlapping or not.
Is this possible?
Edit: If you really want to align the 3rd div using positioning, then you can do it like so:
.parent {
padding: 10px;
background: grey;
position: relative;
}
.child {
background: green;
display: block;
position: relative;
width: 50px;
}
.stacked {
position: relative;
left: 0px;
}
.three {
position: absolute;
left: 200px;
top: 10px;
}
<div class="parent">
<div class="child stacked">div1</div>
<div class="child stacked">div2</div>
<div class="child three">div3</div>
</div>
You can use the column-count property like so:
.parent {
padding: 10px;
background: grey;
column-count: 2;
}
.child {
background: green;
display: block;
width: 50px;
}
<div class="parent">
<div class="child">div1</div>
<div class="child">div2</div>
<div class="child">div3</div>
</div>
Or you can use flexbox to wrap vertically, like so:
.parent {
padding: 10px;
background: grey;
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 50px;
}
.child {
background: green;
display: block;
width: 50px;
}
<div class="parent">
<div class="child">div1</div>
<div class="child">div2</div>
<div class="child">div3</div>
</div>
Here's using grid:
.parent {
padding: 10px;
background: grey;
display: grid;
grid-auto-flow: column;
grid-template-rows: 1fr 1fr;
}
.child {
background: green;
display: block;
width: 50px;
}
<div class="parent">
<div class="child">div1</div>
<div class="child">div2</div>
<div class="child">div3</div>
</div>
Try this :
wrap div3 item in another div and give it a class property of flex-container.
.flex-container {
align-content: flex-start;
}
Ensure the flex direction is horizontal.

Flexbox keep wrapping point while increasing item width

First of all, here is a codepen with the issue I am trying to solve.
This is a simplified version of the problem I have on an actual project. My goal is to keep the grid in the same format with 5 columns and to be able to increase the width of these cells so the content is always visible, but also so that it doesn't wrap before the first row of 5 columns is displayed. Whenever I try to increase the width of the cells the grid wraps and I lose the structure I want.
So, basically, increase width of items, but prevent wrapping, is it possible? It is fine if the content overflows the flex container itself, the goal is to add overflow-x to this grid.
.flex-container {
border: 1px solid silver;
display: flex;
width: 50%;
}
.wrap {
flex-wrap: wrap;
}
.wrap div {
background: gold;
}
.flex-item {
width: 160px;
border-bottom: 1px solid black;
border-right: 1px solid black;
line-height: 100px;
color: black;
font-weight: bold;
font-size: 2em;
text-align: center;
}
<div class="flex-container wrap">
<div class="flex-item">11111111111111</div>
<div class="flex-item">22222222222222</div>
<div class="flex-item">33333333333333</div>
<div class="flex-item">44444444444444</div>
<div class="flex-item">55555555555555</div>
<div class="flex-item">66666666666666</div>
<div class="flex-item">77777777777777</div>
<div class="flex-item">88888888888888</div>
<div class="flex-item">99999999999999</div>
<div class="flex-item">00000000000000</div>
</div>
From the comments, it does look like grid is the option you need, it won't allow content to be wrapping and justify content will stick it on the side if shorter thant the width of the container.
here is the snippet with grid:
/* flex turned into grid */
.flex-container {
border: 1px solid silver;
display: grid;
grid-template-columns:repeat(5,auto);
justify-content:start;
overflow:auto;
width: 80%;
}
.wrap {
}
.wrap div {
background: gold;
}
.flex-item {
border-bottom: 1px solid black;
border-right: 1px solid black;
line-height: 100px;
color: black;
font-weight: bold;
font-size: 2em;
text-align: center;
}
<div class="flex-container wrap">
<div class="flex-item">11111111111111</div>
<div class="flex-item">22222222222222</div>
<div class="flex-item">33333333333333</div>
<div class="flex-item">44444444444444</div>
<div class="flex-item">55555555555555</div>
<div class="flex-item">66666666666666</div>
<div class="flex-item">77777777777777</div>
<div class="flex-item">88888888888888</div>
<div class="flex-item">99999999999999</div>
<div class="flex-item">00000000000000</div>
</div>
I think, if it is allowable, that css grid may be a better candidate for the layout you are proposing...
.grid-container {
border: 1px solid silver;
display: grid;
width: 50%;
grid-template-columns: 20% 20% 20% 20% 20%; /* hard set five columns and no more */
}
.grid-container div {
background: gold;
}
.grid-item {
/* width: 160px; */
border-bottom: 1px solid black;
border-right: 1px solid black;
line-height: 100px;
color: black;
font-weight: bold;
font-size: 2em;
text-align: center;
overflow-x: hidden; /* overflow-x to hide overflow as discussed in question */
}
<div class="grid-container">
<div class="grid-item">11111111111111</div>
<div class="grid-item">22222222222222</div>
<div class="grid-item">33333333333333</div>
<div class="grid-item">44444444444444</div>
<div class="grid-item">55555555555555</div>
<div class="grid-item">66666666666666</div>
<div class="grid-item">77777777777777</div>
<div class="grid-item">88888888888888</div>
<div class="grid-item">99999999999999</div>
<div class="grid-item">00000000000000</div>
</div>
.flex-container {
display: flex;
flex-wrap: wrap;
background-color:red;
}
.flex-container > div {
background-color: #f1f1f1;
width: 100px;
margin: 10px;
text-align: center;
line-height: 75px;
font-size: 30px;
word-wrap: break-word;
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div class="flex-container">
<div>11111111111111</div>
<div>22222222222222</div>
<div>33333333333333</div>
<div>44444444444444</div>
<div>55555555555555</div>
<div>66666666666666</div>
<div>77777777777777</div>
<div>88888888888888</div>
<div>99999999999999</div>
<div>00000000000000</div>
</div>
</body>

How to place two square divs side by side covering the width of their parent

I want .board element to have a square aspect ratio. I want to show two of them side by side, together covering the width of their parent.
I don't want to use width: 50%, because I want to position .wrap element with display: flex.
.board {
position: relative;
background: red;
width: 100%;
height: 0;
padding-bottom: 100%;
border: 1px solid black;
}
.wrap {
display: flex;
}
<div class="wrap">
<div class="board"></div>
<div class="board"></div>
</div>
When I do it like this, I get two divs with squashed width.
Use aspect-ratio and flex:1
.board {
position: relative;
background: red;
flex:1;
aspect-ratio:1/1;
border: 1px solid black;
}
.wrap {
display: flex;
}
<div class="wrap">
<div class="board"></div>
<div class="board"></div>
</div>
Alternatively flex:1 and padding-bottom:50%;
.board {
position: relative;
background: red;
flex: 1;
padding-bottom: 50%;
border: 1px solid black;
}
.wrap {
display: flex;
}
<div class="wrap">
<div class="board"></div>
<div class="board"></div>
</div>

Make empty Div in Flex 100% Height

Using the following my .divider <div> is not showing. I guess this is because it is empty. If I add a "." in there, then I see it. Is it possible to make it 100% the height of the .wrapper without adding content?
.wrapper {
display: flex;
background-color: orange;
}
.left {
background-color: gray;
}
.divider {
background-color: green;
cursor: ew-resize;
width: 12px;
height: 100%;
}
.right {
flex-grow: 1;
background-color: yellow;
}
<div class="wrapper">
<div class="left">Left</div>
<div class="divider"></div>
<div class="right">Right</div>
</div>
https://jsfiddle.net/sub7fxk5/
Remove height: 100%; for .divider
.wrapper {
display: flex;
background-color: orange;
}
.left {
background-color: gray;
}
.divider {
background-color: green;
cursor: ew-resize;
width: 12px;
/* height: 100%; */
}
.right {
flex-grow: 1;
background-color: yellow;
}
<div class="wrapper">
<div class="left">Left</div>
<div class="divider"></div>
<div class="right">Right</div>
</div>
Removing the height and adding flex: 1 seems to help.
Is the result of the code below what you expect it to be?
The wrapper has no height, that means that setting a height to 100% would equal setting the height to 0.
the flex: 1 makes the item flexible even though it has no content and it shows.
Of course you can set a width too. So width: 12px would work. As would width: 100%; (which would push the left and right item to the other side)
You might also use a pseudo-element ::after as a divider. That would clean up your html a bit.
.wrapper {
display: flex;
background-color: orange;
}
.left {
background-color: gray;
}
.divider {
background-color: green;
cursor: ew-resize;
flex: 1;
}
.right {
flex-grow: 1;
background-color: yellow;
}
<div class="wrapper">
<div class="left">Left<br/><br/>Left</div>
<div class="divider"></div>
<div class="right">Right</div>
</div>

Chrome flexbox 100% height inside other 100% height flexbox overflows

I am trying to make a full height page using flexboxes, where the content also uses a flexbox. The page should look as follows example of what it should look like. The blue div is dynamic and could change in height and the red content should take up the remaining space of the content div. This works on both Firefox and IE, however on Chrome it overflows. Can somebody explain why it overflows on Chrome?
The HTML is as follows:
<body>
<div class="container">
<div class="navbar">Navbar</div>
<div class="content">
<div class="container">
<div class="fill"></div>
<div class="dynamic">Here is some dynamic content<br>Test</div>
</div>
</div>
</div>
</body>
And the CSS is:
body{
margin:0;
}
.container{
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
.navbar{
background-color: #ccc;
flex: none;
}
.content{
background-color: #333;
flex: auto;
padding: 10px;
}
.dynamic{
background-color: #0066ff;
flex: none;
}
.fill{
flex: auto;
background-color: #ff0000;
}
Here is an updated snippet.
Use flex:1 for the container that needs to adjust the height automatically.
body {
margin: 0;
}
.container1 {
display: flex;
flex-direction: column;
width: 100%;
height: 100vh;
}
.navbar {
background-color: #ccc;
}
.content {
flex: 1;
background-color: #ff0000;
border: 10px solid #333;
border-bottom: none;
}
.dynamic {
background-color: #0066ff;
border: 10px solid #333;
border-top: none;
}
<body>
<div class="container1">
<div class="navbar">Navbar</div>
<div class="content">
</div>
<div class="dynamic">Here is some dynamic content
<br>Test</div>
</div>
</body>