"align-items: flex-start" aligns children along parent's available space [duplicate] - css

This question already has answers here:
How does flex-wrap work with align-self, align-items and align-content?
(2 answers)
Closed 5 years ago.
I am trying to align each child DIRECTLY after one another (vertically). Apparently align-items: flex-start doesn't do that completely because there is some auto-spacing between each child.
Below is a snippet of the result I get. The children align themselves along their parent's available space, which is not what I like to achieve. What I want is each child to align directly after its previous sibling (vertically, as in the snippet).
Thanks in advance!
EDIT: flex-flow: column wrap and align-content: flex-start both did the trick. I forgot, however, to add align-self: flex-end to the last child, which doesn't work when either of the two solutions above is applied.
* {
box-sizing: border-box;
}
#container {
position: fixed;
top: 0; right: 0; bottom: 0; left: 0;
display: flex;
align-items: flex-start;
flex-flow: row wrap;
}
#container > div {
width: 100%;
margin: 10px;
border: 2px solid #ff0000;
}
#container > div:nth-child(1) { height: 5%; }
#container > div:nth-child(2) { height: 10%; }
#container > div:nth-child(3) { height: 20%; align-self: flex-end; }
<div id="container">
<div></div>
<div></div>
<div></div>
</div>

You need to set align-content: flex-start on parent element because initial value is stretch.
stretch
If the combined size of the items along the cross axis is less than the size of the alignment container, any auto-sized items have their size increased equally (not proportionally), while still respecting the constraints imposed by max-height/max-width (or equivalent functionality), so that the combined size exactly fills the alignment container along the cross axis.
* {
box-sizing: border-box;
}
#container {
position: fixed;
top: 0; right: 0; bottom: 0; left: 0;
display: flex;
align-items: flex-start;
flex-flow: row wrap;
align-content: flex-start;
}
#container > div {
width: 100%;
margin: 10px;
border: 2px solid #ff0000;
}
#container > div:nth-child(1) { height: 5%; }
#container > div:nth-child(2) { height: 10%; }
#container > div:nth-child(3) { height: 20%; }
<div id="container">
<div></div>
<div></div>
<div></div>
</div>
Update: Another solution is to set flex-direction: column then you can use margin to position specific flex item.
* {
box-sizing: border-box;
}
#container {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: flex;
flex-direction: column;
}
#container > div {
width: calc(100% - 20px);
margin: 10px;
border: 2px solid #ff0000;
}
#container > div:nth-child(1) {
height: 5%;
}
#container > div:nth-child(2) {
height: 10%;
}
#container > div:nth-child(3) {
height: 20%;
margin-top: auto;
}
<div id="container">
<div></div>
<div></div>
<div></div>
</div>

You need to set column for the flow
#container {
position: fixed;
top: 0; right: 0; bottom: 0; left: 0;
display: flex;
align-items: flex-start;
flex-flow: column wrap;
}
#container > div:nth-child(3) { height: 20%; margin-top: auto; }
Updated:
Add margin top auto to the last child
https://jsfiddle.net/qghsgze5/2/

Related

Overlapping two boxes

I have been trying to have two boxes in CSS, one in the upper right hand corner of the other. I have been trying to nest divs and use relative positioning but I cannot figure out how to do it. Can someone help me? (Not using z index)
If I understand correctly that you want one box to be inside the other, you can achieve this using position: relative and moving the inner box using top, right, left and bottom.
I recommend diving in to the MDN page for CSS position for more information.
.box1, .box2 {
display: inline-block;
}
.box1 {
width: 200px;
height: 200px;
background: green;
}
.box2 {
position: relative;
width: 100px;
height: 100px;
top: -100px;
left: -100px;
background: orange;
}
<div class='box1'></div>
<div class='box2'></div>
You can use something like this. Using flexBox to align them and giving a negative margin to second box.
*,
*::before,
*::after {
box-sizing: border-box;
}
body {
min-height: 100vh;
margin: 0;
background-color: bisque;
display: grid;
place-content: center;
}
.container{
display: flex;
flex-direction: row;
}
.first{
height: 5rem;
width: 5rem;
background-color: tomato;
}
.second{
margin-top:-50%;
height: 5rem;
width: 5rem;
background-color: tomato;
}
<div class="container">
<div class="first"></div>
<div class="second"></div>
</div>
Based on Marcos answer i think i understand you wrong.
Here is a simple way get the result that you want. You can use position:relative to parent and position: absolute to child item. Then you can move child element inside. top:0; will take you to top corner and right:0; will take you to right corner.
*,
*::before,
*::after {
box-sizing: border-box;
}
body {
min-height: 100vh;
margin: 0;
background-color: bisque;
display: grid;
place-content: center;
}
.parent{
width: 10rem;
height: 10rem;
background-color: tomato;
position: relative;
}
.child {
width: 5rem;
height: 5rem;
background-color: aqua;
position: absolute;
top:0;
right: 0;
}
<div class="parent">
<div class="child"></div>
</div>
Spontaneously, I can think of two possibilities. 1) Work with 'position' or 2) work with 'margin'.
here an example with margin in combination flexbox;
.w {
background-color: lightgray;
display: flex;
justify-content: center;
padding: 20px;
}
.a, .b {
width: 150px;
height: 150px;
}
.a {
background-color: lightblue;
}
.b {
background-color: lightgreen;
margin-top: 20px;
margin-left: -20px;
}
<div class="w">
<div class="a">A</div>
<div class="b">B</div>
</div>

CSS How to resize an image towards the div

I have a div with a text on the left part of it:
* {padding: 0%;margin: 0%;}
body {background-color: brown;}
.content_box {
height: 100%;
display: flex;
flex-direction: row;
background-color: brown;
padding: 1em;
border-radius: 0.5rem;
}
.content_box div {
display: flex;
flex-direction: column;
overflow: hidden;
margin-right: 1rem;
}
.content_box img {
object-fit: cover;
width: 30%;
/*height: 100%;
width: auto;
max-width: 100%;*/
}
.content_box .credentials {color: beige;}
.content_box .left {margin-left: auto;}
.content_box .right {margin-right: 100px;}
<div class='content_box'>
<div class='left'>
<div class='credentials'>Username</div>
<p>Posted message</p>
<div class='credentials'>01/01/2021</div>
</div>
<div class='right'>
...
</div>
</div>
I want to add an image on the right part of it. But it has to be set to the size of text(so if we have three lines of text image will be bigger than if we had one line of text, even if the image with 3 lines is 30x30 pixels, and 1 line text is 1024x1024 pixels)
I would love it if someone could edit my question because I'm not too good at English...
You could position the .content_box relative and the .right div absolute. So you can give it the height of it's parent. Finally give the image a max-height of 100%:
.content_box {
position: relative;
height: auto;
}
.right {
position: absolute;
height: 100%;
width: auto;
top: 0;
right: 0;
background-color: red;
}
.right img {
max-height: 100%;
width: auto;
}

flexbox align items shifted from center without fillers

Centering a flex item is easy. However I like to shift it upwards a bit so that the the relation between the upper and lower space is e. g. 1/2. Easy too when using fillers. But is there a way to do this whithout fillers?
HTML:
<div id="filler-top"></div>
<div id="the-item">
</div>
<div id="filler-bottom"></div>
CSS:
#the-item {
width: 80vw;
height: 30vh;
border: 2px solid lightblue;
}
body {
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
}
#filler-top {
width: 100%;
flex: 1;
}
#filler-bottom {
width: 100%;
flex: 2;
}
https://jsfiddle.net/Sempervivum/b2wotc8e/3/
Applying margin-top and margin-bottom doesn't work as a percentage is relative to the width.
instead of adding 2 elements to the markup, you can use :before and :after pseudo-elements:
#the-item {
width: 80vw;
height: 30vh;
border: 2px solid lightblue;
}
body {
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
}
body:before {
content: "";
width: 100%;
flex: 1;
}
body:after {
content: "";
width: 100%;
flex: 2;
}
<div id="the-item"></div>
Another option is to simply use a mixture of position:relative, top and transform:
#the-item {
width: 80vw;
height: 30vh;
border: 2px solid lightblue;
position: relative;
top: 33.333%;
transform: translateY(-33.333%);
}
body {
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
}
<div id="the-item"></div>

Full browser width bar using negative margins

I'm trying to follow this tutorial:
https://css-tricks.com/full-browser-width-bars/#article-header-id-0
What I need, is my <header> element to be a max-width of 800px, centered in the middle of the page. Then inside that header bar, I will be having a #filtersBar div that will go across the whole body of the page (edge to edge). This is what my code comes out with so far:
Here is a fiddle:
https://jsfiddle.net/us2jsmLy/3/
html, body {
overflow-x: hidden;
}
header {
position: relative;
width: 100%;
margin: 0 auto;
max-width: 1200px;
z-index: 250;
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
background:red;
justify-content: space-between;
}
#filtersBar {
position: relative;
background: green;
width: 100%;
max-width: 800px;
margin: 0 -9999rem;
padding: 0.25rem 9999rem;
z-index: 1;
}
#filtersBarInner {
position: relative;
width: 100%;
max-width: 800px;
background-color: blue;
z-index: 2;
}
<header>
foo bar some contents
<div id="filtersBar">
<div id="filtersBarInner">
dddd
</div>
</div>
</header>
I must be missing something stupid :/
As I understand, you can use :before pseudo for the full background edge to edge and also apply margin:0 to body
Updated Fiddle
html,
body {
overflow-x: hidden;
margin: 0;
}
div#filtersBar:before {
content: "";
position: absolute;
background: green;
top: 0;
bottom: 0;
left: -1000px;
right: -1000px;
z-index: -1;
}
header {
position: relative;
width: 100%;
margin: 0 auto;
max-width: 800px;
z-index: 250;
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
background: red;
justify-content: space-between;
}
#filtersBar {
position: relative;
background: green;
width: 100%;
max-width: 800px;
z-index: 1;
padding: 15px 0;
}
#filtersBarInner {
position: relative;
width: 100%;
max-width: 800px;
/*margin: 0 auto;*/
background-color: blue;
z-index: 2;
}
<header>
foo bar some contents
<div id="filtersBar">
<div id="filtersBarInner">
<p>
ddddd
</p>
<p>
ddddd
</p>
<p>
ddddd
</p>
<p>
ddddd
</p>
</div>
</div>
</header>

Vertical centering with flexbox when items have :after background images

How do I vertically center divs inside their container using flexbox if those divs have background images attached to their :after pseudo-element?
On Chrome 33 these divs align to the top: http://jsfiddle.net/6SQ6W/
HTML:
<div id="container">
<div id="left_and_right">
<div>Left</div>
<div>Right</div>
</div>
</div>
CSS:
#container {
height: 300px;
width: 300px;
background: blue;
color: white;
position: relative;
}
#container #left_and_right {
position: absolute;
height: 100%;
width: 100%;
display: -webkit-box;
display: -webkit-flex;
display: flex;
align-items: center;
}
#container #left_and_right div, #container #left_and_right div:after {
height: 50px;
width: 100px;
}
#container #left_and_right div {
background: green;
/* THIS PREVENTS VERTICAL CENTERING BUT SEEMS NEEDED FOR THE REST OF THE STUFF */
position: absolute;
}
#container #left_and_right div:after {
content:"";
position: absolute;
background-image: url(http://www.animatedgif.net/lipsmouth/kissing_e0.gif);
text-indent: -9999px;
left: 0;
}
#container #left_and_right div:nth-of-type(2) {
right: 0;
}

Resources