Flex items not wrapping in column-direction flexbox - javascript

I have an outerWrapper, innerWrapper, and children. outerWrapper has a height of 300px, and is display: flex. innerWrapper is also display: flex, and is flex-direction: column.
When I add align-items with a value of anything but stretch to outerWrapper, the children display one long column. They ignore the 300px height. Here's an image of how it displays:
It should display like this:
Just with align-items: flex-end.
Why is this happening, and how can I use align-items: flex-end and have the children display like the second image?
JSFiddle
#outerWrapper {
height: 300px;
background-color: lightgreen;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: flex-end;
}
ul {
padding: 0;
margin: 0;
display: flex;
align-items: center;
flex-wrap: wrap;
flex-direction: column;
}
li {
list-style-type: none;
width: 100px;
height: 100px;
background-color: lightblue;
border: 1px solid;
}
<div id="outerWrapper">
<ul id="innerWrapper">
<li class="child">I'm #01</li>
<li class="child">I'm #02</li>
<li class="child">I'm #03</li>
<li class="child">I'm #04</li>
<li class="child">I'm #05</li>
</ul>
</div>
Update
The answer to this question, is to add a height of 210px to innerWrapper. But I need to get to that number using JavaScript, because the amount of boxes will be dynamic.
I tried the following code:
innerWrapper.style.height = (lastChild.offsetTop - innerWrapper.offsetTop + lastChild.offsetHeight) + 'px';
but it didn't fix it. It just made the height to: 5 * 102 (5 = number of boxes; 102 = height + border).
How can I set the correct height to innerWrapper using JavaScript? (I can't do height: 100% because I won't be able to set align-items: flex-end or center.)
JSFiddle
var innerWrapper = document.getElementById('innerWrapper');
var lastChild = innerWrapper.lastElementChild;
newHight = lastChild.offsetTop - innerWrapper.offsetTop + lastChild.offsetHeight;
innerWrapper.style.height = newHight + 'px';
#outerWrapper {
height: 300px;
background-color: lightgreen;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: flex-end;
}
ul {
padding: 0;
margin: 0;
display: flex;
align-items: center;
flex-wrap: wrap;
flex-direction: column;
/*height: 206px;*/
}
li {
list-style-type: none;
width: 100px;
height: 100px;
background-color: lightblue;
border: 1px solid;
}
<div id="outerWrapper">
<ul id="innerWrapper">
<li class="child">I'm #01</li>
<li class="child">I'm #02</li>
<li class="child">I'm #03</li>
<li class="child">I'm #04</li>
<li class="child">I'm #05</li>
</ul>
</div>

You've defined a height for #outerWrapper: height: 300px.
Just give the child – #innerWrapper – an equal height: height: 100%. Now they wrap.
Then, if you want the items positioned at the container bottom, use flex auto margins on the odd-numbered items.
Use an invisible pseudo-element to make the last odd-numbered item always align with the top row.
#outerWrapper {
height: 300px;
background-color: lightgreen;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: flex-end;
}
ul {
padding: 0;
margin: 0;
display: flex;
align-items: center;
flex-wrap: wrap;
flex-direction: column;
height: 100%; /* NEW */
}
li {
list-style-type: none;
width: 100px;
height: 100px;
background-color: lightblue;
border: 1px solid;
}
li:nth-child(odd) { margin-top: auto; } /* NEW */
ul::after {
content: ""; /* NEW */
width: 100px; /* NEW */
height: 100px; /* NEW */
border: 1px solid; /* NEW */
visibility: hidden; /* NEW */
}
<div id="outerWrapper">
<ul id="innerWrapper">
<li class="child">I'm #01</li>
<li class="child">I'm #02</li>
<li class="child">I'm #03</li>
<li class="child">I'm #04</li>
<li class="child">I'm #05</li>
</ul>
</div>
Revised Fiddle

Try adding the height of the flexbox container:
ul {
...
height: 100%;
}

Since both the outerWrapper and menu element have flex positioning, you'll have to make some adjustments to the menu elements' dimensions and alignment as well. Here's an updated fiddle with the behavior you're looking for / matches the second image:
https://jsfiddle.net/wtyqo1su/1/
#outerWrapper {
width: 100%;
height: 300px;
background-color: lightgreen;
display: flex;
justify-content: center;
align-items: center;
}
ul {
height: 250px;
width: 300px;
padding: 0;
margin: 0;
display: flex;
flex-wrap: wrap;
flex-direction: column;
align-items: center;
}
li {
list-style-type: none;
width: 100px;
height: 100px;
background-color: lightblue;
border: 1px solid;
}
I restricted the ul to a specific width / height (so the children would actually wrap as expected). Let me know if you have any questions!

Related

How to create multiple row with two columns in React app

Well, in my react app, I want multiple rows having two columns. Just like first pink picture below.
But I am getting it like this. The divs are floating on the left side only, and nothing is working.
I think there should be a solution for using in map method. react component code.
{dog.map((data) => (
<div key={data.id} className="dogs-list">
<div id={data.id} className="first-column">
<img src={dogPic} alt="dog"></img>
<h3>Dog's Name</h3>
<h3>{data.name}</h3>
</div>
</div>
))}
Nothing is working. Can anyone please help?
this is the styling of this area.
.page .dogs-list {
/* display: flex; */
color: white;
width: 100%;
}
.page .dogs-list .first-column {
width: 50%;
/* border: 2px yellow solid; */
/* display: flex;
flex-direction: column; */
float: right;
}
.dogs-list img {
height: 250px;
width: 100%;
}
.dogs-list h3 {
display: flex;
align-items: center;
justify-content: center;
padding-bottom: 10px;
font-size: 18px;
}
Looking forward!
If you do not have a given structure to follow, (there was none mentioned?) try the following.
.dogs-list {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.dog{
width: calc(50% - 4px);
background-color: beige;
border: 2px yellow solid;
display: flex;
flex-direction: column;
}
.dogs-list img {
height: 250px;
width: 100%;
}
.dogs-list h3 {
display: flex;
align-items: center;
justify-content: center;
padding-bottom: 10px;
font-size: 18px;
}
<div className='dogs-list'>
{dog.map(data => (
<div id={data.id} className='dog'>
<img src={data.dogPic} alt='dog' />
<h3> Dog 's Name</h3> <h3> {data.name} </h3>
</div>
))}
</div>

CSS flex a content-fit image with a title sibling of unknown height [duplicate]

This question already has answers here:
Why don't flex items shrink past content size?
(5 answers)
Closed 2 years ago.
I'm trying to flex the img and .title elements within a flex-column. When the page is resized the image should grow/shrink while maintaining its aspect ratio and the title text should remain the same height at the bottom of the screen. However, when I reduce the screen height the title text is pushed off the screen.
Also, the height of the .title element may not always be a single line, will not be known prior to rendering.
Code: https://jsfiddle.net/qk4wbfpe/
body {
height: 100vh;
margin: 0;
padding: 0;
overflow: hidden;
}
.container {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
.container > img {
flex-grow: 1;
flex-shrink: 1;
background-color: blue;
width: 100%;
height: 100%;
object-fit: contain;
}
.container .title {
padding: 10px;
color: white;
text-align: center;
background-color: gray;
}
<div class="container">
<img src="https://cdn.mos.cms.futurecdn.net/paWPwF85Vkcs8YUuyvA3YM-650-80.jpg.webp">
<div class="title">
Planet Earth
</div>
</div>
If you add min-height:0 to .container>img it will give the desired result.
body {
height: 100vh;
margin: 0;
padding: 0;
overflow: hidden;
}
.container {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
.container>img {
flex-grow: 1;
flex-shrink: 1;
background-color: blue;
width: 100%;
min-height:0;
object-fit: contain;
}
.container .title {
padding: 10px;
color: white;
text-align: center;
background-color: gray;
}
<div class="container">
<img src="https://cdn.mos.cms.futurecdn.net/paWPwF85Vkcs8YUuyvA3YM-650-80.jpg.webp">
<div class="title">
Planet Earth
</div>
</div>
add a wrap to your container to make it flow nicely
.container {
display: flex;
flex-wrap: wrap;
flex-direction: column;
width: 100%;
height: 100%;
and add a flex-basis on your child (img)
.container > img {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 25%;
background-color: blue;
object-fit: contain;
or you can remove the flex-grow, shrink and shorthand it to
flex: 1 1 25%;
is that what you needed?

How to center arrows verticaly relative to the picture in slick slider when i have text under image?

On picture you can see thet my arrows are top:50% relative to height of slide container
[1]: https://i.stack.imgur.com/DjEZh.png
I made a quick demo on Codepen: https://codepen.io/basti-n/pen/NWNRKYX?editors=1111
<div class="main-content">
<div class="arrow-left"><</div>
<img src="https://hatrabbits.com/wp-content/uploads/2017/01/random.jpg" alt="elephant">
<div class="arrow-right">></div>
</div>
<div class="description">
<caption>Lorem Ipsum</caption>
</div>
</div>
body {
box-sizing: border-box;
height: 100vh;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
}
.container {
display: flex;
flex-flow: column;
align-items: center;
}
.main-content {
display: flex;
align-items: center;
img {
height: 300px;
width: auto;
margin: 0 10px;
}
}
.description {
margin-top: 12px;
}

flexbox list column-reverse and start from top

I want to display Latest chat person 1st position(active) with firebase but firebase have not date field. so i am tring date number of milliseconds with flexbox column-reverse that will start from top but not from bottom. I have tried with position but not working.
Would you please give me a good way to do this.
.container {
display: flex;
flex-direction: column-reverse;
/*flex-flow: flex-start;*/
justify-content: flex-end;
align-items: flex-start;
height: 700px;
width: 100%;
background: blue;
position: absolute;
overflow:auto;
}
.box {
position: relative;
display: flex;
align-items: center;
justify-content: center;
margin: 20px;
width: 50px;
height: 50px;
background-color: red;
top:0px;
}
.active{
order:1;
}
<ul class="container">
<li class="box">1</li>
<li class="box">2</li>
<li class="box active">3</li>
<li class="box">4</li>
<li class="box">5</li>
<li class="box">6</li>
</ul>
Change justify-content property to flex-end - see demo below:
.container {
display: flex;
flex-direction: column-reverse;
/*flex-flow: flex-start;*/
justify-content: flex-end; /* CHANGED */
align-items: flex-start;
height: 700px;
width: 100%;
background: blue;
position: absolute;
overflow:auto;
}
.box {
position: relative;
display: flex;
align-items: center;
justify-content: center;
margin: 20px;
width: 50px;
height: 50px;
background-color: red;
top:0px;
}
<ul class="container">
<li class="box">1</li>
<li class="box">2</li>
<li class="box">3</li>
<li class="box">4</li>
<li class="box">5</li>
<li class="box">6</li>
</ul>
I was in the same situation, how I hacked it is by having the flex property - order saved in firebase for every post. Flex has an order property which you can set. It makes the ordering of elements very easy.
Just set order property and value fetched from firebase to your every post.
Here is the link of the page, I have used it on: https://hackinbits.com/blog
Here is the link to the MDN docs: Set https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Ordering_Flex_Items#The_order_property

Responsive elements hidden when no space

I dont really know what exacly write.
I have 4 boxes with width 300px, if document width is (I dont know maybe) 600px then 2 boxes should stay at page and others should be hide.
Is there a way to make it dynamic? Maybe js or jquery? Hope you can help me with this! ^^
Here is what I have now.
HTML
<html>
<head>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</head>
<body>
<article class='Conteiner' id='howItWorks'>
<section class='Conteiner-Highlight howItWorks-Highlight'>Jak to działa?</section>
<section class='Steps'>
<section class='step'><div class='digit'>1</div><span class='digit-description'>Analizujemy <br> potrzeby klienta</span></section>
<section class='step_hidden'><div class='digit'>2</div><span class='digit-description'>Tworzymy <br> projekt graficzny</span></section>
<section class='step_hidden'><div class='digit'>3</div><span class='digit-description'>Przedstawiamy <br> propozycję klientowi</span></section>
<section class='step_hidden'><div class='digit'>4</div><span class='digit-description'>Przystępujemy <br> do pisania strony</span></section>
</section>
<section class='steps-Controls'>
<span class='steps_check'>
<i class='material-icons'>radio_button_checked</i>
<i class='material-icons'>radio_button_unchecked</i>
<i class='material-icons'>radio_button_unchecked</i>
<i class='material-icons'>radio_button_unchecked</i>
</span>
<span class='steps_arrows'>
<span class='step_arrow' id='step_arrow_left'><i class='material-icons'>keyboard_arrow_left</i></span>
<span class='step_arrow' id='step_arrow_right'><i class='material-icons'>keyboard_arrow_right</i></span>
</span>
</section>
</article>
</body>
</html>
SCSS
:root{
--red: rgb(231,76,77);
--white: rgb(242,241,244);
--darker-blue: rgb(14,60,91);
}
*{
margin:0;
padding: 0;
box-sizing: border-box;
}
html, body{
width: 100%;
height: 100vh;
color: #0E3C5B;
font-size: 16px;
}
/* Modern browsers */
#media screen and (min-width: 25em){
html { font-size: calc( 16px + (24 - 16) * (100vw - 400px) / (800 - 400) ); }
}
/* Safari <8 and IE <11 */
#media screen and (min-width: 25em){
html { font-size: calc( 16px + (24 - 16) * (100vw - 400px) / (800 - 400) ); }
}
#media screen and (min-width: 50em){
html { font-size: calc( 16px + (24 - 16) * (100vw - 400px) / (800 - 400) ); }
}
.Conteiner-Highlight{
width: 100%;
height: 100px;
font-family: Roboto;
font-weight: 900;
display: flex;
justify-content: center;
align-items: center;
margin: 50px auto;
font-size: 1.2rem;
}
.Conteiner{
width: 100%;
min-height: 1000px;
height: auto;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
border-bottom: 1px solid rgb(14,60,91);
}
#howItWorks{
.Steps{
width: 80%;
height: auto;
display: flex;
justify-content: center;
align-items: center;
flex-flow: row;
.step , .step_hidden{
max-width: 300px;
width: 80%;
max-height: 500px;
height: 60vh;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
box-shadow: 0px 4px 10px rgba(144,144,144,.5);
margin: 0 50px;
border-bottom: 10px solid rgb(231,76,77);
padding: 10px;
transition: all .3s ease-in-out;
opacity: 1;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
.digit{
height: 40%;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
font-size: 3rem;
font-family: Roboto;
font-weight: 900;
color: rgb(231,76,77);
}
.digit-description{
height: 30%;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
font-size: .5rem;
font-family: Raleway;
font-weight: 400;
}
}
.step_hidden{
opacity: .3;
}
.arrow{
width: 80px;
height: 80px;
display: flex;
align-items: center;
justify-content: center;
}
}
.steps-Controls{
width: 100%;
height: 100px;
display: flex;
justify-content: center;
align-items: center;
flex-flow: column;
margin: 50px 0;
.steps_arrows{
display: flex;
flex-flow: row;
margin: 10px 0;
cursor:pointer;
.step_arrow{
display: flex;
justify-content: center;
align-items: center;
width: 35px;
height: 35px;
margin: 0 10px;
background-color: var(--red);
i{
color: var(--white);
}
}
}
.steps_check{
display: flex;
flex-flow: row;
cursor:pointer;
i{
font-size: .4rem;
}
}
}
}
CodePen
There are several ways to do this.
You could just make the css-container of those elements non-wrapping, so if there isn't enough space, they are just not visisble by window-size.
In this scenario it is possible to see 2 + 1/2 Elements when you resize the window because they "disappear" gradualy.
The other solution is just to use javascript. You could write a function that is fired on each resize-event and write an if-condition where those elements' visibility is hidden when the window-size gets too small.
For both solutions there are plenty of examples and documentation out there, so i would just suggest you search for those and pick one that is easy to understand for you and fit's your situation.
edit: Since other comments on your question came up: If you only make your decision based on the whole viewport-size, then you can use #media-queries. You can't use them if you are depending not on the viewport but some outer html-element and layouting.
You can achive this by media queries. if you expand the snippet you can see all other hidden boxes.
.container{
display: flex;
flex-direction : row;
}
.container .box{
margin: 5px;
background-color : #333;
width : 50px;
height: 50px;
}
#media screen and ( max-width: 982px ) {
.container .box:not(:first-of-type){
display:none;
}
}
<div class="container">
<div class="box">
</div>
<div class="box">
</div>
<div class="box">
</div>
<div class="box">
</div>
</div>
example according to you code :
https://codepen.io/anon/pen/EeOgxE
I don't really know what exactly (to) reply ;)
You could skip script entirely and go with CSS, assuming that each box is 300px wide and 600px combined, you could do something like this:
/* Showing 2 */
#media (min-width: 600px)
{
.my-container-with-four-boxes {
width: 600px;
height: 300px;
overflow: hidden;
}
}
/* Showing 3 */
#media (min-width: 900px)
{
.my-container-with-four-boxes {
width: 900px;
height: 300px;
overflow: hidden;
}
}
/* Showing 4 */
#media (min-width: 1200px)
{
.my-container-with-four-boxes {
width: 1200px;
height: 300px;
}
}
You'd probably have to adjust the screen limitations and container sizes with padding or something else not mentioned here ;)

Categories