Switching flex items from row to column alignment - css

I have a 'card' like html component, that it displays this way:
+------+-----------------+-------+
| 1 | 2 | 3 |
+------+-----------------+-------+
And when I go under the 720px I want that became like this:
+------+-------------------------+
| | 2 |
| 1 +-------------------------+
| | 3 |
+------+-------------------------+
I am having difficulties to figure out how can I achieve this with flexbox. I am wondering if it is the right solution for this kind of problem.
the initial state, is currently like this:
<div class="card">
<div class="status"></div>
<div class="title">Tryout.it</div>
<div class="details">156 emails</div>
<div class="action"><button>go</div>
</div>
and my CSS something like this:
.card {
margin: 10px;
min-width: 320px;
min-height: 42px;
background-color: white;
border: 1px solid #eee;
border-radius: 6px;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
padding: 9px 10px;
}
.card .status {
width: 30px;
height: 24px;
}
.card .title {
flex-grow: 1;
}

You cannot achieve this with flexbox with your current HTML structure.
(In the future you can use the grid layout for this, but at the moment it is not supported.)
However, if you place 2 and 3 in a container you can do this:
.card {
margin: 10px;
border: 1px solid #eee;
border-radius: 6px;
display: flex;
justify-content: space-between;
padding: 9px 10px;
}
.card .avatar {
width: 30px;
height: 24px;
}
.card .container {
flex-grow: 1;
display: flex;
flex-wrap: wrap;
}
.card .container .name {
width: 50%;
}
.card .container .presentation {
flex-grow: 1;
}
#media (max-width: 720px) {
.card .container .name {
width: 100%;
}
}
<div class="card">
<div class="avatar">
x
</div>
<div class="container">
<div class="name">Mr. Potato</div>
<div class="presentation">Hi!</div>
</div>
</div>

You can use CSS media query to apply a different style your div's at a certain screen size.
#media screen and (max-width: 720px) {
.css-class {
}
#css-id {
}
}

#ciaoben, Since you disappeared after asking you question, I'll provide an answer based upon the logic that the .title and .details blocks are meant to be blocks 2 and 3 from your diagram and that the .action is meant to be a fourth block on the opposite side.
Simply put, you need another layer for your HTML structure before you can apply the CSS to adjust it. You would wrap the blocks you want to have the appearance of altered in another DIV.
Once you have the HTML structure updated, it's a simple matter of applying a #media query to adjust the appearance at the desired screen size.
Please see my example below. Note: I updated your CSS to a more streamlined flexbox approach. Further, it applis display: flex to the .action block because, as I noted above, you don't identify it at all.
.card {
margin: 10px;
min-width: 320px;
min-height: 42px;
background-color: white;
border: 1px solid #eee;
border-radius: 6px;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
padding: 9px 10px;
}
.card .status {
width: 30px;
}
.card .stretchit, .card .action {
-webkit-flex: 1;
flex: 1;
}
#media screen and (min-width: 720px) {
.card .stretchit {
display: flex;
}
.card .title, .card .details {
-webkit-flex: 1;
flex: 1;
}
}
<div class="card">
<div class="status"></div>
<div class="stretchit">
<div class="title">Tryout.it</div>
<div class="details">156 emails</div>
</div>
<div class="action"><button>go</button></div>
</div>

Related

Flexbox positioning of elements [duplicate]

This question already has answers here:
Make a div span two rows in a grid
(2 answers)
Closed 4 months ago.
The community reviewed whether to reopen this question 4 months ago and left it closed:
Original close reason(s) were not resolved
Hi this is my example layout on mobile device.
https://codesandbox.io/s/cocky-dust-xuurof?file=/src/styles.css
On the wider screen the third element must be the same width like a second yellow element. The second and the third element. The second and third items together are the same height as the first item. The html structure cannot change, I need use Flexbox, not css grid.
.App {
font-family: sans-serif;
text-align: center;
display: flex;
border: 2px solid black;
flex-wrap: wrap;
}
.one {
background-color: red;
flex-basis: 120px;
height: 80px;
}
.two {
background-color: yellow;
flex-grow: 1;
}
.three {
background-color: green;
height: 30px;
flex-basis: 100%;
}
#media only screen and (min-width: 500px) {
.one {}
.two {}
.three {}
}
<div class="App">
<div class="one">1</div>
<div class="two">2</div>
<div class="three">3</div>
</div>
I modified the media query to account for this snippet.
You should see "Large Screen" results in the snippets "Full Page" mode.
.App {
font-family: sans-serif;
text-align: center;
display: flex;
border: 2px solid black;
flex-wrap: nowrap;
}
.one {
background-color: red;
width: 120px;
height: 80px;
align-items: stretch;
}
.two {
background-color: yellow;
flex: 4 1 auto;
}
.three {
background-color: green;
height: initial;
flex: 4 1 auto;
}
#media screen and (width < 1024px) {
.App {
flex-wrap: wrap;
}
.two {
flex: 4 0 auto;
}
.three {
height: 30px;
flex: 4 0 100%;
}
}
<div class="App">
<div class="one">1</div>
<div class="two">2</div>
<div class="three">3</div>
</div>

two-column sticky flexbox scrolling not working [duplicate]

This question already has an answer here:
Why is 'position: sticky' not working with Core UI's Bootstrap CSS
(1 answer)
Closed 1 year ago.
I'm having trouble getting my flexbox two-column setup to work.
Basically I just want the left column to be sticky while scrolling down the right one and then end scrolling at the exact same point.
It should also be collapsible as in the example below.
It's supposed to substitute this solutions i made using a regular grid which I'm unfortunately not able use anymore.
You can see my current progress below - I'm not really able to figure out what to do from here - as I'm a rookie I hoped you guys would know.
.wrapper {
display: flex;
flex-flow: row wrap;
overflow: auto;
gap: 2em;
justify-content: flex-start;
height: auto;
font-weight: bold;
text-align: center;
}
.wrapper > * {
padding: 10px;
flex: 1 100%;
}
.aside-1 {
position: -webkit-sticky;
position: sticky;
background: gold;
height: auto;
top: 0;
align-self: flex-start;
}
.aside-2 {
background: hotpink;
height: 900px;
top: 0;
}
#media all and (min-width: 300px) {
.aside { flex: 1 0 0; }
}
<section class="page-width">
<div class="wrapper">
<aside class="aside aside-1"><img width="100%" src="https://cdn.shopify.com/s/files/1/0044/2852/9698/files/242370040_4238706352865614_2798039132201744827_n.jpg"> Aside 1
</aside>
<aside class="aside aside-2">
Aside 2
</aside>
</div>
</section>
I've checked the forum without really finding what I need and hope that somebody would be able to help me :o) Thanks a million!
Remove overflow:auto on parent container of sticky element to make stickiness work
.wrapper {
display: flex;
flex-flow: row wrap;
gap: 2em;
justify-content: flex-start;
height: auto;
font-weight: bold;
text-align: center;
}
.wrapper > * {
padding: 10px;
flex: 1 100%;
}
.aside-1 {
position: -webkit-sticky;
position: sticky !important;
background: gold;
top: 0 !important;
align-self: flex-start;
}
.aside-2 {
background: hotpink;
height: 900px;
top: 0;
}
#media all and (min-width: 300px) {
.aside { flex: 1 0 0; }
}
.other-content{
margin-top: 2rem;
height: 20rem;
width: 100%;
background: red;
position:sticky;
top:0;
}
<section class="page-width">
<div class="wrapper">
<aside class="aside aside-1"><img width="100%" src="https://cdn.shopify.com/s/files/1/0044/2852/9698/files/242370040_4238706352865614_2798039132201744827_n.jpg"> Aside 1
</aside>
<aside class="aside aside-2">
Aside 2
</aside>
</div>
<div class="divider"></div>
<div class="other-content"></div>
</section>

CSS Flexbox not working for navigation (mobile screen)

First off I am very new to CSS and following an online course.
I am trying to create a navigation bar that changes from row to column when going into mobile. I am using flexbox and #media queries for that however, it seems like my code does not make any change to the navigation direction when going to mobile. Please help! ]
.container {
display: flex;
color: white;
justify-content: flex-end;
}
.box {
width: 90px;
height: 3rem;
margin: 0.5rem;
background-color: black;
text-align: center;
}
.box-four {
width: 100px;
}
#media screen and (max-width: 600px) {
.container {
flex-direction: row;
justify-content: center;
flex-grow: 2rem;
flex-wrap: wrap;
flex-basis: 10%;
}
}
Can't say exactly what problems you are having without seeing some example HTML to work with but at first glance it seems you should be using flex-direction:column for your mobile view.
Note well: What is in the media query is your mobile styles in this case. You can tell because you have specified max-width which means that it will apply to all screen sizes below the width provided (600px).
See the below as an example which incorporates your provided CSS with some basic HTML I made. (Resize the browser window to test).
.container {
display: flex;
color: white;
}
.box {
width: 90px;
height: 3rem;
margin: 0.5rem;
background-color: black;
text-align: center;
}
.box-four {
width: 100px;
}
#media screen and (max-width: 600px) {
.container {
flex-direction: column;
justify-content: center;
flex-grow: 2rem;
flex-wrap: wrap;
flex-basis: 10%;
}
}
<div class="container">
<div class="box">Entry 1</div>
<div class="box">Entry 2</div>
<div class="box">Entry 3</div>
<div class="box">Entry 4</div>
</div>
You can also read more about flex-direction at the MDN Web Docs

3 expandable column landscape page in pure CSS

If this can be achieved in CSS:
When not hovered: 3 columns split in average width
When hovered on one of the column: that column expands and squeezes other 2 columns
Here's what I've been trying:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* vertical 1:2:1 */
html,
body {
height: 100%;
}
.vertical-divider {
display: flex;
flex-flow: column nowrap;
height: 100%;
}
/* container in page center */
.container {
display: flex;
flex-flow: row nowrap;
background-color: #eee;
flex: 2;
}
.container>.item {
display: flex;
flex-flow: column;
justify-content: left;
align-content: left;
align-items: left;
transition: .3s;
max-width: 50%;
padding-top: 24px;
padding-left: 12px;
background-color: #ccc;
min-width: 10%;
flex: 1;
text-align: left;
}
.container>.item:hover {
transition: .3s;
max-width: 80% !important;
background: #333;
flex: 4;
cursor: pointer;
color: #fff;
}
<!doctype html>
<html>
<head>
</head>
<body>
<div class="vertical-divider">
<div class="container">
<div class="item">
Column 1
</div>
<div class="item">
Column 2
</div>
<div class="item">
Column 3
</div>
</div>
</div>
</body>
</html>
But responsive design (e.g. If I want to just put them vertically if the screen is narrow) seems hard to achieve. So I'm asking if there is a better solution.
Flexbox offers a clean, modern solution. We can transition on the flex property. If you want to make the hovered div take up more room, simply adjust the value to a higher number.
.container {
display: flex;
}
.container > div {
flex: 1;
border-right: 2px solid black;
height: 300px;
padding: 10px;
transition: 0.5s flex;
}
.container > div:hover {
flex: 3;
}
.container > div:last-child {
border-right: 0;
}
<div class="container">
<div>col 1</div>
<div>col 2</div>
<div>col 3</div>
</div>
Edit A new requirement has emerged: make it responsive. Flexbox makes this an easy addition by changing the flex-direction property inside a simple media query.
#media screen and (max-width: 700px) {
.container {
flex-direction: column;
height: 100vh;
}
.container > div {
border-right: none;
border-bottom: 2px solid;
}
}
With the media query in place, our example is now complete.
Have a look.

flexbox how to achieve this specific layout?

Like in the image - http://i65.tinypic.com/aa7ndw.png Examples and live flex configurators are explain only simple examples, or I just don't get it.
Will I be able to use media queries to for example not display a4 when < 800px?
I have always used float and flex is somehow 'different' anyway I would like to know it better, so any help is appreciated.
flex specific example
Apply display: flex to a container and its child elements will be displayed in flex. For this layout, you will want to wrap the elements when width is already filled for the current row.
The header and footer will be width: 100%, taking a full row. #a3 and #a4 will have flex: 1 to distribute the width of their row, taking each one 50% of the width.
div.flex-container{
width: 200px;
height: 300px;
background-color: black;
display: flex;
flex-flow: row wrap;
}
#a1, #a2{
width: 100%;
}
#a3, #a4{
flex: 1;
}
#a5, #a6, #a7{
height: 50px;
width: 80%;
margin: auto;
margin-bottom: 1rem;
}
/* Example styles */
div{
text-align: center;
}
#a1{
background-color: red;
}
#a2{
background-color: limegreen;
}
#a3{
background-color: royalblue;
}
#a4{
background-color: cyan;
}
#a5, #a6, #a7{
background-color: fuchsia;
}
<div class="flex-container">
<div id="a1">a1</div>
<div id="a3">a3</div>
<div id="a4">a4
<div id="a5">a5</div>
<div id="a6">a6</div>
<div id="a7">a7</div>
</div>
<div id="a2">a2</div>
</div>
And yeah, you can use media queries as normal
div.flex-container{
width: 200px;
height: 300px;
background-color: black;
display: flex;
flex-flow: row wrap;
}
#a1, #a2{
width: 100%;
}
#a3, #a4{
flex: 1;
}
#a5, #a6, #a7{
height: 50px;
width: 80%;
margin: auto;
margin-bottom: 1rem;
}
#media (max-width: 800px){
#a4{
display: none;
}
}
/* Example styles */
div{
text-align: center;
}
#a1{
background-color: red;
}
#a2{
background-color: limegreen;
}
#a3{
background-color: royalblue;
}
#a4{
background-color: cyan;
}
#a5, #a6, #a7{
background-color: fuchsia;
}
<div class="flex-container">
<div id="a1">a1</div>
<div id="a3">a3</div>
<div id="a4">a4
<div id="a5">a5</div>
<div id="a6">a6</div>
<div id="a7">a7</div>
</div>
<div id="a2">a2</div>
</div>

Resources