How do I set 100% height of outer element for inner - html

I have a flexbox 'table' where I'm basically trying to put an interesting thing on the top. The problem I've encountered is being unable to write it in HTML
My current result
The result I'm trying to get
I have tried to do it without inner divs and spans, by doing margin:auto but unfortunately it relocates borders from the left and right to the middle :( So the code for the current result is:
.flex-container {
width: auto;
height: 100vh;
display: flex;
flex-direction: column;
}
.flex-container .middle {
flex: 1;
display: flex;
}
.top {
padding-top: 30px;
border: 2px solid #05788D;
display:flex;
}
.leftSide {
padding-top: 30px;
display: flex;
flex-wrap: wrap;
flex-basis: 50%;
overflow: auto;
border: 2px solid #05788D;
}
.rightSide {
padding-top: 30px;
display: flex;
flex-wrap: wrap;
flex-basis: 50%;
overflow: auto;
border: 2px solid #05788D;
border-left-style: none;
}
.firstOption
{
border: 2px solid #05788D;
border-top-style: none;
border-bottom-style:none;
}
.anotherOption
{
border: 2px solid #05788D;
border-top-style: none;
border-bottom-style:none;
border-left-style:none;
}
<div class="flex-container">
<div class="top">
<div style="width:50%;">
<span class="firstOption">One option</span>
</div>
<div style="width:50%;">
<span class="anotherOption">Another option</span>
</div>
</div>
<div class="middle">
<div class="leftSide">
left
</div>
<div class="rightSide">
right
</div>
</div>
</div>

Simply use text-align to control text-alignment of your span and use padding inside your span and don't forget to make them inline-block:
.flex-container {
width: auto;
height: 100vh;
display: flex;
flex-direction: column;
}
.flex-container .middle {
flex: 1;
display: flex;
}
.top {
border: 2px solid #05788D;
display: flex;
}
.top div {
flex:1;
}
.leftSide {
padding-top: 30px;
display: flex;
flex-wrap: wrap;
flex-basis: 50%;
overflow: auto;
border: 2px solid #05788D;
}
.rightSide{
display: flex;
flex-wrap: wrap;
flex-basis: 50%;
overflow: auto;
border: 2px solid #05788D;
border-left-style: none;
}
.firstOption {
text-align:right;
}
.firstOption span,.anotherOption span{
border: 2px solid #05788D;
padding-top: 30px;
display:inline-block;
}
<div class="flex-container">
<div class="top">
<div class="firstOption"><span>One option</span></div>
<div class="anotherOption"><span>Another option</span></div>
</div>
<div class="middle">
<div class="leftSide">
left
</div>
<div class="rightSide">
right
</div>
</div>
</div>

You've added padding-top: 30px to class="top". Instead, the inner child (which are 50%) should have padding-top:30px;
While of course this can be done in a better way, above is the quickest solution to your problem.

You could use justify-content: flex-end on the left option to make it position at the end of the div. I applied the suggested changes to your code in this fiddle.
I can really recommend this guide!

Related

How do I align text in top left corner of div?

Trying to align a number in the top left corner of a div square. Justify content is moving it correctly, but I can't seem to get align-items OR align-self to move the text vertically.
Thoughts? And thank you for your help
body{
display: flex;
justify-content: center;
align-items: center;
}
.grid {
margin: o;
display: grid;
grid-template-columns: repeat(10, 45px);
gap: 10px;
list-style-type: none;
}
.cell {
display: flex;
justify-content: left;
align-self: flex-start;
background-color: grey;
height: 50px;
width: 50px;
border-style: solid;
border-width: 2px;
border-color: black;
}
(I'll update my answer with more specific code samples, once you've shared your markup)
Option #1 - Absolute Positioning
.wrapper {
position: relative;
min-height: 300px;
border: 2px dashed red;
}
.top-left {
position: absolute;
top: 0.25rem;
left: 0.25rem;
border: 2px dashed blue;
}
<div class="wrapper">
<div class="top-left">[123]</div>
</div>
Option #2 - Flex Layout
.wrapper {
display: flex;
justify-content: flex-start;
align-items: baseline;
min-height: 300px;
border: 2px dashed red;
}
.top-left {
border: 2px dashed blue;
}
<div class="wrapper">
<div class="top-left">[123]</div>
</div>
Option #3 - Grid Layout
.wrapper {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
min-height: 200px;
border: 2px dashed red;
}
.top-left {
grid-column-start: 1;
grid-column-end: 1;
border: 2px dashed blue;
}
.cell {
border: 2px dashed yellow;
}
<div class="wrapper">
<div class="top-left">[123]</div>
<div class="cell">[CELL]</div>
<div class="cell">[CELL]</div>
<div class="cell">[CELL]</div>
<div class="cell">[CELL]</div>
<div class="cell">[CELL]</div>
<div class="cell">[CELL]</div>
<div class="cell">[CELL]</div>
<div class="cell">[CELL]</div>
</div>
To vertically align the text in the top left corner of your .cell divs, you can use the align-items: flex-start property on the .cell class like this:
.cell {
display: flex;
justify-content: left;
align-items: flex-start;
background-color: grey;
height: 50px;
width: 50px;
border-style: solid;
border-width: 2px;
border-color: black;
}
This will vertically align the content of the .cell divs along the top edge of the divs.

How to truncate the text between the children of a flexbox child?

I understand how to truncate the text which is wrapped inside a flex child however this particular case seems a bit complicated.
The desired behaviour is that the text between the two blue blocks should get truncated to keep them inside the red border.
.container {
display: flex;
align-items: center;
justify-content: space-between;
border: 1px solid black;
padding: 10px;
width: 300px;
}
.block {
display: inline-block;
width: 50px;
height: 50px;
}
.container .left {
min-width: 0;
white-space: nowrap;
padding: 10px;
border: 1px solid red;
}
.left .label {
display: inline-block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.left .block {
background-color: blue;
}
.container .right {
padding: 10px;
border: 1px solid blue;
}
.right .block {
background-color: red;
}
<div class="container">
<div class="left">
<div class="block">
</div>
<div class="label">
Is this the real life?
</div>
<div class="block">
</div>
</div>
<div class="right">
<div class="block">
</div>
</div>
</div>
Is this what you are looking for? Basically i added flexbox property for left and right div
.container {
display: flex;
align-items: center;
justify-content: space-between;
border: 1px solid black;
padding: 10px;
width: 300px;
}
.block {
display: inline-block;
width: 50px;
height: 50px;
}
.left {
display: flex;
justify-content: space-between;
align-items: flex-end;
min-width: 0;
white-space: nowrap;
padding: 10px;
border: 1px solid red;
}
.label {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.block {
background-color: blue;
}
.right {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
border: 1px solid blue;
}
.right .block {
background-color: red;
}
<div class="container">
<div class="left">
<div class="block">
</div>
<div class="label">
Is this the real life?
</div>
<div class="block">
</div>
</div>
<div class="right">
<div class="block">
</div>
</div>
</div>

How to vertically align items with different sizes?

I'm facing a issue of vertically aligning items when a div contains nested child elements, please check: https://codepen.io/akashpen0501/pen/rNaGgXv
Note, the container has a fixed height of 200px & I want them children to be centered vertically
Current result:
I want to align all divs vertically center, as
Required:
.container {
display: flex;
flex-flow: row;
align-items: center;
border: 1px solid black;
height:200px;
}
.container div {
margin: 10px;
padding: 10px;
border: 1px solid black;
}
.container span {
display: block;
}
<div class="container">
<div>left</div>
<div>center<span class="nested child">nested content</span></div>
<div>right</div>
</div>
Please advice.
try align-items: flex-start on the container
.container{
display: flex;
flex-flow: row;
align-items: self-start;
border: 1px solid black;
}
.container div{
margin: 10px;
padding: 10px;
border: 1px solid black;
}
.container span{
display: block;
}
<div class="container">
<div>left</div>
<div>center<span class="nested child">nested content</span></div>
<div>right</div>
</div>
You can approximate this using baseline alignment and pseudo element. Change baseline with center in the below example to see that left/right will stay at the same place.
.container {
display: flex;
flex-flow: row;
align-items: baseline;
border: 1px solid black;
height:200px;
background:linear-gradient(red,red) center/100% 1px no-repeat
}
.container:before {
content:"";
height:calc(50% + 0.25em)
}
.container div {
margin: 10px;
padding: 10px;
border: 1px solid black;
}
.container span {
display: block;
}
<div class="container">
<div>left</div>
<div>center<span class="nested child">nested content</span></div>
<div>right</div>
</div>
<div class="container">
<div>left</div>
<div>center</div>
<div>right</div>
</div>
.container {
display: flex;
align-items: flex-start; // <----- here
border: 1px solid black;
}
.container div {
margin: 10px;
padding: 10px;
border: 1px solid black;
}
.container span {
display: block;
}
<div class="container">
<div>left</div>
<div>center<span class="nested child">nested content</span></div>
<div>right</div>
</div>
Wrap your child components inside a <div> and give then class .children with following properties, it will keep your content vertically aligned and horizontally at the same height.
.children{
display: flex;
align-items: flex-start;
}
.container {
display: flex;
flex-flow: row;
align-items: center;
border: 1px solid black;
height:200px;
}
.container div {
margin: 10px;
padding: 10px;
border: 1px solid black;
}
.container span {
display: block;
}
.children{
display: flex;
align-items: flex-start;
}
<div class="container">
<div class=children>
<div>left</div>
<div>center<span class="nested child">nested content</span></div>
<div>right</div>
</div>
</div>

Stretch columns in two columns layout with shared header using flexbox

I'm using flexbox to create a two-columns layout with a header row.
* {
box-sizing: border-box;
position: relative;
}
.container {
border: 2px solid gray;
display: flex;
flex-wrap: wrap;
height: 300px;
}
.header {
flex-basis: 100%;
border: 2px solid magenta;
height: 50px;
line-height: 50px;
text-align: center;
}
.column1 {
flex-basis: 150px;
/* height: calc(100% - 50px); */
border: 2px solid green;
}
.column2 {
/* height: calc(100% - 70px); */
flex: 1;
border: 2px solid orange;
}
<div class='container'>
<div class='header'>it's a header</div>
<div class='column1'>column 1</div>
<div class='column2'>column 2</div>
</div>
Feel free to see the full example here.
As you can see in the example there is a gap between columns and header. My aim is to stretch columns vertically to fill whole empty space in the container.
I can achieve it by setting height property like calc(100% - <header-height>). Is it the correct way?
I just tried to use "flex" style and set align-items: stretch to the container and align-self: stretch to columns but without success. Did I probably miss something trying to implement it this way?
I think specifying flex-direction as column is appropriate in this case.
The second row is itself a flex element with the flex-direction: row. You can fill the rest of the remaining space using flex: 1, which is equivalent to flex-grow: 1.
* {
box-sizing: border-box;
}
.container {
border: 2px solid gray;
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 300px;
}
.header {
border: 2px solid magenta;
height: 50px;
line-height: 50px;
text-align: center;
}
.subcontainer {
display: flex;
flex-direction: row;
flex: 1;
}
.column1 {
flex-basis: 150px;
border: 2px solid green;
}
.column2 {
flex: 1;
border: 2px solid orange;
}
<div class='container'>
<div class='header'>it's a header</div>
<div class="subcontainer">
<div class='column1'>column 1</div>
<div class='column2'>column 2</div>
</div>
</div>
Do it like shown below
* {
box-sizing: border-box;
}
body,
html {
height: 100%;
}
.container {
border: 2px solid gray;
display: flex;
flex-direction: column;
height: 100%;
}
.header {
width: 100%;
border: 2px solid magenta;
height: 50px;
line-height: 50px;
text-align: center;
}
.body-container {
display: flex;
width: 100%;
flex: 1;
}
.column1 {
width: 50%;
border: 2px solid green;
}
.column2 {
width: 50%;
border: 2px solid orange;
}
<div class='container'>
<div class='header'>it's a header</div>
<div class="body-container">
<div class='column1'>column 1</div>
<div class='column2'>column 2</div>
</div>
</div>

Prevent double borders around side-by-side elements

If you have multiple containers with 1px border, all containers next to each other generate a 2px border. So in order to get rid of that you always set e.g. border-right: none; and then add border-right: 1px; to the last child to make all containers have 1px border in all sides.
But if you use flexbox flex-basis rule to break containers into next line, it breaks whole border-right idea, the last container in the line before the break always stays left out with no border.
e.g. in this example I have 5 containers, but I want 4 per line and when it breaks into new line, you can see the border-right issue:
.wrapper {
display: flex;
flex-wrap: wrap;
width: 400px;
}
.container {
flex-basis: 20%;
border: 1px solid #000;
border-right: none;
margin-bottom: 1px;
min-height: 100px;
width: 100px;
display: flex;
justify-content: center;
align-items: center;
}
.container:last-child {
border-right: 1px solid #000;
}
<div class="wrapper">
<div class="container">1</div>
<div class="container">2</div>
<div class="container">3</div>
<div class="container">4</div>
<div class="container">5</div>
</div>
https://jsfiddle.net/45kngj9p/
Since you know how many flex items there are in each row, you can use the :nth-child() selector to apply borders to items missed by the main rule.
.wrapper {
display: flex;
flex-wrap: wrap;
width: 400px;
}
.container {
flex-basis: 20%;
border-top: 1px solid #000;
border-bottom: 1px solid #000;
border-right: 1px solid #000;
margin-bottom: 1px;
min-height: 100px;
display: flex;
justify-content: center;
align-items: center;
}
.container:nth-child(4n + 1) { /* add border to first child in each row */
border-left: 1px solid red;
}
<div class="wrapper">
<div class="container">1</div>
<div class="container">2</div>
<div class="container">3</div>
<div class="container">4</div>
<div class="container">5</div>
</div>
<hr>
<div class="wrapper">
<div class="container">1</div>
<div class="container">2</div>
<div class="container">3</div>
</div>
<hr>
<div class="wrapper">
<div class="container">1</div>
<div class="container">2</div>
<div class="container">3</div>
<div class="container">4</div>
<div class="container">5</div>
<div class="container">6</div>
<div class="container">7</div>
<div class="container">8</div>
<div class="container">9</div>
<div class="container">10</div>
</div>
Remove Border:none; and add margin-left:-1px;
.container {
flex-basis: 20%;
border: 1px solid #000;
margin-left:-1px;
margin-bottom: 1px;
min-height: 100px;
width: 100px;
display: flex;
justify-content: center;
align-items: center;
}
That's it!
You can try these solutions:
1
Here you don't need the .container:last-child styles.
.container {
flex-basis: 20%;
border: 1px solid #000;
margin-bottom: 1px;
margin-right: -1px;
min-height: 100px;
width: 100px;
display: flex;
justify-content: center;
align-items: center;
}
2
This one works for boxes number 4, 8, 12, etc.
.container {
flex-basis: 20%;
border: 1px solid #000;
border-right: none;
margin-bottom: 1px;
min-height: 100px;
width: 100px;
display: flex;
justify-content: center;
align-items: center;
}
.container:last-child,
.container:nth-child(4n) {
border-right: 1px solid #000;
}