Flexbox two divs next each other and responsive - html

I am creating an Layout for my project and I am working with Flexbox (see image and css style). Well it seems to be working but not for mobile. For example if I resise the screen then the columns will be resize but the right column (Map) is not jumping below the content. How can I do it?
HTML
<div class="container">
<div class="header"><h1>HEADER</h1></div>
<div class="main">
<div class="leftSide">
<div class="menuItem">Menu Item</div>
<div class="secondItem">Content</div>
</div>
<div class="rightSide">
<div class="thirdItem">Map</div>
</div>
</div>
</div>
CSS
// Layout start page
.container {
display: flex;
flex-direction: column;
}
.header{
border: 5px solid yellowgreen;
}
.main{
display: flex;
flex-wrap: wrap;
}
.leftSide{
flex:0 0 65%;
border: 5px solid red;
}
.rightSide{
flex: 1;
border: 5px solid black;
}
.menuItem {
border: 5px solid purple;
}

Add this to your CSS, change the width to whatever you need.
#media (max-width: 600px) {
.main{
display: flex;
flex-wrap: wrap;
flex-direction: column
}
}
Codepen: https://codepen.io/anon/pen/XPmMdQ

Related

Moving div to the right inside flexbox while keeping space-around width

So I am trying to move a div to the right inside flexbox.
I dont want to change justify-content to anything else, but I am trying to move the middle div to the right. However if I use margin and move it then the space around the whole parent div is also affected. Is it possible to move the middle div to the right without affecting the space of the whole div?
So far this solution kind of works- but the items will overlay on each other on smaller screen so this is not responsive at all:
.item2 {
margin-left: 100px;
margin-right: -100px;
border: 1px solid red;
}
But it doesnt seem very elegant. Is there a way to do it with flexbox only?
.main {
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
}
.item1 {
border: 1px solid red;
}
.item2 {
margin-left: 100px;
margin-right: -100px;
border: 1px solid red;
}
<div class="main">
<div class="item1">
Item 1
</div>
<div class="item2">
Item 2
</div>
<div class="item1">
Item 3
</div>
</div>
CSS transform can alter the positioning of an element but it doesn't affect surrounding elements.
This snippet removes the margin settings and instead uses transform: translateX(100px).
.main {
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
}
.item1 {
border: 1px solid red;
}
.item2 {
/*margin-left: 100px;
margin-right: -100px;
*/
transform: translateX(100px);
border: 1px solid red;
}
<div class="main">
<div class="item1">
Item 1
</div>
<div class="item2">
Item 2
</div>
<div class="item1">
Item 3
</div>
</div>
I think you could utilize the order property here
.main {
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
}
.item1 {
border: 1px solid red;
}
.item2 {
order: 3;
border: 1px solid red;
}
<div class="main">
<div class="item1">
Item 1
</div>
<div class="item2">
Item 2
</div>
<div class="item1">
Item 3
</div>
</div>
You can do it in several ways:
1)
transform: translateX(100px)
2)
position: relative;
left: 100px;
3) if you want to change order of flex-items, use this:
.flex-item-2{
order: 1
}
It moves second item to third. Because default order value: 0.
Maybe there are other useful ways you can use!
.main {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.item1 {
border: 1px solid red;
}
.rightSide{
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
}
.item2 {
border: 1px solid red;
}
<div class="main">
<div class="item1 leftSide">
Item 1
</div>
<div class="rightSide">
<div class="item2">
Item 2
</div>
<div class="item1">
Item 3
</div>
</div>
</div>
.main {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
}
.parent {
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
}
.p-1{
flex-grow: 2;
}
.p-2{
flex-grow: 1;
}
.item1 {
border: 1px solid red;
}
.item2 {
border: 1px solid red;
}
.item3 {
border: 1px solid red;
}
<div class="main">
<div class="parent p-1">
<div class="item1">
Item 1
</div>
</div>
<div class="parent p-2">
<div class="item2">
Item 2
</div>
<div class="item3">
Item 3
</div>
</div>
</div>

Trying to modify the width of the columns in this flexbox

I am trying to render rows with the date on the left and some text on the right.
I cant seem to work out how I changed the widths of the columns though?
Currently my day and text column are the same width.
I'd like to have the day as 50px and the text as 300px.
Is it possible with this code?
.sb-flex-row {
flex-direction: row;
display: flex;
}
.sb-flex-column {
flex-direction: column;
display: flex;
}
.sb-flex-body {
display: flex;
}
.sb-flex-body div:not([class*="flex"]) {
border: 1px solid white;
flex: 1 1 50px;
width: 200px;
}
<div class="sb-flex-body">
<div class="sb-flex-row">
<div style="background: #0980cc;">day</div>
</div>
<div class="sb-flex-column">
<div style="background: #09cc69;">month</div>
<div style="background: #cc092f;">year</div>
</div>
<div class="sb-flex-row">
<div style="background: #0980cc;">text</div>
</div>
</div>
I cleaned up and make it maybe simpler for you to understand. You have an outer wrapper that is flexible. The default direction is row and that is ok. Then you have two blocks. one block dateBlock and the second is a text block. the dateblock contains two blocks (a,b). and b you can assign the direction to the column. Afterward, you can assign the width to the text block and Dateblock. That is it :-)
.wrapper {
display: flex;
gap:10px;
}
.dateBlock {
display: flex;
background: yellow;
gap: 20px;
padding: 10px;
box-sizing: border-box;
}
.textBlock {
background: green;
padding: 10px;
box-sizing: border-box;
width: 300px;
}
.monthYear {
display: flex;
flex-direction: column;
width:50px;
}
.day {
font-size: 30px;
width: 50px;
}
<div class="wrapper">
<div class="dateBlock">
<div class="day">day</div>
<div class="monthYear">
<div>month</div>
<div>year</div>
</div>
</div>
<div class="textBlock">text</div>
</div>
I rearranged your markup a bit to easily target these divs in the style sheet. You can see the changes I made to your CSS under /* changes */. Also, take note of the HTML I adjusted.
.sb-flex-row {
flex-direction: row;
display: flex;
}
.sb-flex-column {
flex-direction: column;
display: flex;
}
.sb-flex-body {
display: flex;
}
/* changes */
.sb-flex-body div:not([class*="flex"]) {
border: 1px solid white;
width: 50px;
}
.sb-flex-row > div {
min-width: 300px;
}
<div class="sb-flex-body">
<div class="sb-flex-column">
<div style="background: #0980cc;">day</div>
<div style="background: #09cc69;">month</div>
<div style="background: #cc092f;">year</div>
</div>
<div class="sb-flex-row">
<div style="background: #0980cc;">text</div>
</div>
</div>

Stretching and centering nested 2d flexbox element

.outer {
border: 2px solid red;
display: flex;
}
.inner {
border: 2px solid cyan;
display: flex;
flex-flow: column wrap;
align-self: center;
}
.innest {
border: 2px solid orange;
flex-grow: 1;
}
<div class="outer">
<div class="inner">
<div class="innest">a</div>
<div class="innest">b</div>
<div class="innest">c</div>
</div>
<div class="inner">
<div class="innest">d</div>
</div>
</div>
I've been trying to both stretch and center the 'd' element of the above code example for a while now, but haven't been able to come up with a solution. I have been able to either stretch it vertically, or center it vertically, but not both at the same time. How can I do that?
EDIT: I would like the element with the cyan border to extend the height of its parent (red), while its inner element (orange border) also extends the height of its parent (cyan). All while the 'd' content is being vertically centered.
I guess this is what you're looking for
.outer {
border: 2px solid red;
display: flex;
}
.inner {
border: 2px solid cyan;
display: flex;
flex-flow: column wrap;
align-self: center;
}
.second_inner {
display: flex;
flex-basis: auto;
}
.second_inner .innest {
display: flex;
align-items: center;
}
.innest {
border: 2px solid orange;
}
<div class="outer">
<div class="inner">
<div class="innest">a</div>
<div class="innest">b</div>
<div class="innest">c</div>
</div>
<div class="second_inner">
<div class="innest">d</div>
</div>
</div>

How to set a margin in a HTML element only when there are elements to the right

My question is: How can I put a margin between the 2 elements, without misaligning them in smaller screens?
I'm creating an HTML page with 2 elements disposed along a line, like this:
I made it responsive, so when I have a smaller screen, the elements are wrapped to another line:
Here's a fiddle to this: https://jsfiddle.net/5ye2sc4b/1/
Html:
<div class="container">
<div class="header">Header</div>
<div class="line">
<div class="element element1">Element 1</div>
<div class="element element2">Element 2</div>
</div>
<div class="footer">Footer</div>
</div>
CSS:
.container {
display:flex;
flex-direction: column;
margin-top: 10px;
}
.header, .footer {
background-color: lightblue;
padding: 5px;
margin-bottom: 5px;
margin-top: 5px;
}
.line {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.element {
border: 1px solid gray;
flex-grow: 1;
height: 100px;
}
If I put a right margin in element 1, it will be displayed correctly in bigger screens:
element1 { margin-right: 20px; }
But it will be misaligned to the header on smaller screens:
On the fiddler above I put some buttons to change the global container size, to simulate the problem.
While i think your approach is not the best way to create a responsive layout you might want to simply remove the margin on smaller screens:
#media (max-width: 620px) {
margin-right: 0px
}
I think this is more suitable for CSS grid where you can use gaps:
.container {
/*display: flex;
flex-direction: column; not really useful in this case*/
margin-top: 10px;
}
.header,
.footer {
background-color: lightblue;
padding: 5px;
margin-bottom: 5px;
margin-top: 5px;
}
.line {
display: grid;
/* adjust the 200px to control when elements will wrap */
grid-template-columns:repeat(auto-fit,minmax(200px,1fr));
/* margin only between columns */
grid-column-gap:16px;
}
.element {
border: 1px solid gray;
height: 100px;
}
<div class="container">
<div class="header">Header</div>
<div class="line">
<div class="element element1">Element 1</div>
<div class="element element2">Element 2</div>
</div>
<div class="footer">Footer</div>
</div>
You could do this using media queries:
Make sure your .line has flex-flow: row nowrap; the shorthand code for flex-direction: row;
flex-wrap: nowrap; initially. The children should have a flex-basis of 50%
Then let the media query (#media) do the rest.
As soon as your screen goes below 900px, apply the CSS inside the media query like so:
#media(max-width: 900px){
.line{
flex-flow: row wrap;
}
.element{
flex-basis: 100%;
}
.element1 {
margin-right: 0px;
}
this will remove the margin from your element1 aswell as set the elements to 100% flex basis, aswell as the flex wrap on the .line for it to wrap.
.container {
display:flex;
flex-direction: column;
margin-top: 10px;
}
.header, .footer {
background-color: lightblue;
padding: 5px;
margin-bottom: 5px;
margin-top: 5px;
}
.line {
display: flex;
flex-flow: row nowrap;
}
.element {
border: 1px solid gray;
flex-grow: 1;
height: 100px;
flex-basis: 50%;
}
.element1 { margin-right: 20px; }
#media(max-width: 900px){
.line{
flex-flow: row wrap;
}
.element{
flex-basis: 100%;
}
.element1 {
margin-right: 0px;
}
Html:
<div class="container">
<div class="header">Header</div>
<div class="line">
<div class="element element1">Element 1</div>
<div class="element element2">Element 2</div>
</div>
<div class="footer">Footer</div>
</div>

Flex-wrapping without nested divs

I'm trying to make a horizontal card using flexbox without having nested divs.
For example, what I have right now is this:
.card {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.card-img {
width: 37%;
}
.card-content {
width: 63%;
}
<div class='card'>
<div class='card-img'>
<img src='example' />
</div>
<div class='card-content'>
<div class='card-number'>
</div>
<div class='card-type'>
</div>
</div>
</div>
This layout works for now, but when the viewport resizes, I want the horizontal card to change into a vertical one (which it already does). However, I want to re-order the card-img, card-number, and card-type using flex order.
How could I get this same horizontal layout while using this type of div layout?
Edit:
Sorry for the confusing wording, what I was aiming to do was to create a horizontal layout that works like the image except with 3 separate divs, not 2 divs with 1 being a nested div. Sorry!
.card {
display: flex;
}
.card-img {
flex: 0 0 37%;
border: 1px dashed red;
}
.card-number {
flex: 0 0 30%;
border: 1px dashed red;
}
.card-type {
flex: 1 0 30%;
border: 1px dashed red;
}
img {
width: 100%;
}
.card > div {
display: flex;
align-items: center;
justify-content: center;
}
#media (max-width: 500px) {
.card { flex-direction: column; }
.card-img { order: 3; }
.card-number { order: 2; }
.card-type { order: 1; }
}
<div class='card'>
<div class='card-img'>
<img src="http://i.imgur.com/60PVLis.png">
</div>
<div class='card-number'>555</div>
<div class='card-type'>Orange</div>
</div>
https://jsfiddle.net/7y8sarwn/