I am trying to use flex box for mobile view but it does not seem to work for a specific box(the title flexbox works fine but the labels flex doesnt show). Also, I have divs inside the labels flexbox as child elements
#media screen and (max-width:450px) {
.title {
display: flex;
}
.click {
display: none;
}
.name {
display: flex;
font-size: 50px;
}
.labels {
display: flex;
width: 100%;
background-color: aliceblue;
}
}
<div class="labels">
<div class="port social">Social</div>
<div class="port bio">Bio</div>
<div class="port web">Website</div>
<div class="fancybox fancyboxy-iframe port resume" href="image/Weldons%20resume%20final.pdf" data-fancybox="gallery">Resume</div>
</div>
https://codepen.io/ew39020/pen/MmEmyZ
I found two problems:
In Codepen CSS, row 19: you have diplay instead of display
In your snippet here: Media queries seem not to work here, because result is too wide.
And if you want elements to have equal width, just add flex: 1 to them.
.title {
display: flex;
}
.click {
display: none;
}
.name {
display: flex;
font-size: 50px;
}
.labels {
display: flex;
width: 100%;
background-color: aliceblue;
}
.labels > * {
flex: 1;
}
<div class="labels">
<div class="port social">Social</div>
<div class="port bio">Bio</div>
<div class="port web">Website</div>
<div class="fancybox fancyboxy-iframe port resume" href="image/Weldons%20resume%20final.pdf" data-fancybox="gallery">Resume</div>
</div>
In your CodePen code, you misspelled the display property under labels:
.labels{
diplay:flex; /* missing the `s` */
width:100%;
background:blue;
}
When I corrected this, the flexbox works. I also added a media query condition to test this under a smaller screen, and it worked.
Related
I have 2 elements in a container that properly sticks to left and right edges:
https://jsfiddle.net/jamesjsfiddle/n3ta0Lro/1/
Html:
<div class="subsectionTitle">
<div class="subsectionTitle__title">This is my title! It could potentially be very long.</div>
<div class="subsectionTitle__date">Start date and end date</div>
</div>
CSS:
.subsectionTitle{
font-weight: 700;
position: relative;
}
.subsectionTitle__title{
display: inline-block
}
.subsectionTitle__date{
float: right;
}
But when the viewport becomes too small, output looks like this instead:
I am trying to get it to look like this when the viewport is too small:
What's a smart change I can make to achieve this? Javascript is okay too.
This can be achieved by applying a display: flex property, flex-wrap: wrap and justify-content: space-bewtween to the parent. No need to set a media query! ;)
.subsectionTitle{
font-weight: 700;
position: relative;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
<div class="subsectionTitle">
<div class="subsectionTitle__title">This is my title! It could be very long.</div>
<div class="subsectionTitle__date">December 2020 - July 2020</div>
</div>
Add a media query for a max-width => #media (max-width: 480px){ }
.subsectionTitle {
font-weight: 700;
position: relative;
}
.subsectionTitle__title {
display: inline-block
}
.subsectionTitle__date {
float: right;
}
#media (max-width: 480px) {
.subsectionTitle__date {
float: none;
}
}
<div class="subsectionTitle">
<div class="subsectionTitle__title">This is my title! It could be very long.</div>
<div class="subsectionTitle__date">December 2020 - July 2020</div>
</div>
Uses the #media rule to include a block of CSS properties only if a certain condition is true. add a breakpoint where certain parts of the design will behave differently on each side of the breakpoint.
.subsectionTitle{
font-weight: 700;
position: relative;
}
.subsectionTitle__title{
display: inline-block
}
.subsectionTitle__date{
}
#media only screen and (max-width: 600px) {
.subsectionTitle__date {
float: none;
}
}
This question already has answers here:
Make container shrink-to-fit child elements as they wrap
(4 answers)
Closed 1 year ago.
Below is simple example illustrating the problem. I have "Stackoverflow Stackoverflow" string and in first case it is displayed as a single line and in the second case word wrap happens. As you can see in the second case width of the div element is wider than a single "Stackoverflow" word. Is there a way to get rid of this empty space on the right? Resulting element has width 200px as specified per max-width but I want element to have actual width which is enough to fit it into 200px after word wrap.
body {
font-size: 30px;
}
.row {
margin-bottom: 10px;
}
.text-no-wrap {
background: yellowgreen;
white-space: nowrap;
display: inline-block;
}
.text-wrap {
max-width: 200px;
background: tomato;
white-space: normal;
display: inline-block;
}
<div class="row">
<div class="text-no-wrap">Stackoverflow Stackoverflow</div>
</div>
<div class="row">
<div class="text-wrap">Stackoverflow Stackoverflow</div>
</div>
You could try adding width: max-content; to the div's insde the .row
Note that width: max-content; isn't supported in Internet Explorer, but is supported on all other browsers.
Check the support of width: max-content; here.
I've added flex-direction: column; to the .row so the children of those
div's will appear underneath each other.
If you need display: flex; on the .row div, then This is the way to go. If you don't need display: flex; on the .row div, just simply remove it. And only use width: max-content; on the children;
body {
font-size: 30px;
}
.row {
display: flex;
flex-direction: column;
margin-bottom: 10px;
}
.text-no-wrap {
width: max-content;
background: yellowgreen;
}
.text-wrap {
width: max-content;
background: tomato;
}
<div class="row">
<div class="text-no-wrap">Stackoverflow1 Stackoverflow2</div>
</div>
<div class="row">
<div class="text-wrap">Stackoverflow1 Stackoverflow2</div>
<div class="text-wrap">Stackoverflow1 Stackoverflow2</div>
</div>
I believe this one is not a text-wrap issue. If you check the following code you will get multiple spaces in between wrapping text. This one is due to the
max-width: 200px;
specified for
.text-wrap.
body {
font-size: 30px;
}
.row {
display: flex;
margin-bottom: 10px;
}
.text-no-wrap {
background: yellowgreen;
white-space: nowrap;
}
.text-wrap {
max-width: 200px;
background: tomato;
white-space: normal;
}
<html>
<body>
<div class="row">
<div class="text-no-wrap">Stackoverflow Stackoverflow</div>
</div>
<div class="row">
<div class="text-wrap">Stackoverflow Stackoverflow testing text wrapping space issue</div>
</div>
</body>
</html>
Go through the demo you can see that after "testing text" multiple spaces is there.
I have 5 divs, every second div should have a different colour than the others.
<div class="element element1">Element1</div>
<div class="element element2">Element2</div>
<div class="element element3">Element3</div>
<div class="element element4">Element4</div>
<div class="element element5">Element5</div>
In my CSS I have
.element {
background-color: grey;
}
.element:nth-child(odd) {
background-color: pink;
}
Now dynamically the order of those elements will change, which I want to do with flexbox. Meaning my CSS looks like this then:
.element {
background-color: grey;
display:flex;
}
.element5 {
order: 1;
}
.element2 {
order: 2;
}
As flexbox is not changing the DOM, the nth-child(odd) will still style every second DOM Element, which is not the order the user will see. But that's what I want. Every second element the users sees should have a different colour, even if the element changes the order with flexbox. Has anyone an idea how this could work? I can only use CSS or HTML for this, no JavaScript or PHP.
Assuming the layout is always going to be as you put it above.
First You need to set display flex in a container, not in the elements.
Second, if you set Element 5|2 to order 1|2 respectively they will always be at the end as default order is 0(zero).
so you end with | assume bold is odd new colour
ORIGINAL ORDER(DOM): 1 2 3 4 5
FLEX ORDER: 1 3 4 5 2
.flex-container {
/*SET DISPLAY FLEX ON CONTAINER*/
-ms-box-orient: horizontal;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -moz-flex;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row wrap;
flex-flow: row wrap;
}
/*SET THE NEW ORDER*/
.element:nth-of-type(2){ order: 2;}
.element:nth-of-type(5) { order: 1; }
/*PRESENTATION PROPOUSES ONLY*/
.element,
.normal{
background: grey;
padding: 5px;
width: 100px;
height: 100px;
margin: 5px;
line-height: 100px;
color: white;
font-weight: bold;
font-size: 2em;
text-align: center;
}
/* TARGET NEW ODD ELEMENTS*/
.element:nth-of-type(1),
.element:nth-of-type(2),
.element:nth-of-type(4){
background: pink;
}
/* TARGET ORIGINAL ORDER*/
.normal:nth-child(odd){
background: pink;
}
<h1>FLEX ORDER</h1>
<div class="flex-container">
<div class="element element1">1</div>
<div class="element element2">2</div>
<div class="element element3">3</div>
<div class="element element4">4</div>
<div class="element element5">5</div>
</div>
<h1>ORIGINAL ORDER</h1>
<div class="flex-container">
<div class="normal">1</div>
<div class="normal">2</div>
<div class="normal">3</div>
<div class="normal">4</div>
<div class="normal">5</div>
</div>
If you were to use the Flex & Order only in certain device.Let's say you want default order(12345) in mobile and flex + order(13452) from tablet up you can have #media queries leaving the default(ORIGINAL ORDER) to change colours with nth-child(odd) and then for other devices inside media queries add the above code(FLEX ORDER).
Thanks.
My solution:
div {
display: flex;
flex-direction: column;
}
div > div {
order: 1;
background-color: #868d95;
}
div > div:nth-child(odd) {
background-color: #a7acb2;
}
div > div.active {
order: 0;
background-color: #20c36d;
}
div > div.active ~ div {
background-color: #a7acb2;
}
div > div.active ~ div:nth-child(odd) {
background-color: #868d95;
}
<div>
<div>1</div>
<div>2</div>
<div class="active">3</div>
<div>4</div>
<div>5</div>
<div>7</div>
<div>8</div>
</div>
scss:
div {
display: flex;
flex-direction: column;
& > div {
order: 1;
background-color: #868d95;
&:nth-child(odd) {
background-color: #a7acb2;
}
&.active {
order: 0;
background-color: #20c36d;
& ~ div {
background-color: #a7acb2;
&:nth-child(odd) {
background-color: #868d95;
}
}
}
}
}
I am working on a responsive site and came across an interesting problem. I have some divs side by side. There could be anywhere from 2 to 6 or so of them. When the screen isn't wide enough to show all the content properly, the divs stack vertically. Simple enough to do with CSS.
The problem is, I need them to be in a different order depending on the layout. This is easy to do with 2 or 3 divs (Changing divs order based on width), but significantly more challenging when you add a fourth.
I could use position: absolute; and manually set the position, however this causes the parent to shrink and not contain them properly.
To make this even more complicated, I can't use JavaScript.
Working with two columns:
(untested)
HTML:
<div id="container">
<div class="column-half column-half-2">
First div on mobile, right div on desktop
</div>
<div class="column-half column-half-1">
Second div on mobile, left div on desktop
</div>
</div>
CSS:
.container {
width: 80%;
max-width: 1200px;
margin: 0 auto;
padding-bottom: 20px;
position: relative;
}
.column-half {
display: table-cell;
padding: 25px;
vertical-align: top;
width: 40%;
}
.column-half-1 {
float: left;
}
.column-half-2 {
float: right;
}
HTML, with 4 columns:
<div id="container">
<div class="column-quarter column-quarter-3">
First div on mobile, third div on desktop
</div>
<div class="column-quarter column-quarter-2">
Second div on mobile, second div on desktop
</div>
<div class="column-quarter column-quarter-1">
Third div on mobile, first div on desktop
</div>
<div class="column-quarter column-quarter-4">
Fourth div on mobile, fourth div on desktop
</div>
</div>
This is doable in CSS thanks to the wonderful flexbox spec. Using the order and flex-flow properties, we can achieve what you want. Unprefixed, IE11 and all evergreen browsers will support this. IE10 prefixes -ms-order and doesn't support flex-flow.
The solution takes into consideration all the constraints you listed:
Have a list of elements in a given order displayed as a row.
When the window is too small, change them to display in a column.
Change the order of the elements when they are displayed in a column.
Because of the limitations of Stack Snippets, you'll need to view the demo in Full page mode, and resize your browser to see the effect.
.container div {
width: 100px;
height: 50px;
display: inline-block;
}
.one { background: red; }
.two { background: orange; }
.three { background: yellow; }
.four { background: green; }
.five { background: blue; }
#media screen and (max-width: 531px) {
.container { display: flex; flex-flow: column; }
.five { order: 1; }
.four { order: 2; }
.three { order: 3; }
.two { order: 4; }
.one { order: 5 }
}
<div class="container">
<div class="one">I'm first</div>
<div class="two">I'm second</div>
<div class="three">I'm third</div>
<div class="four">I'm fourth</div>
<div class="five">I'm fifth</div>
</div>
Alternatively, here is a JSFiddle demo.
You can also simply use flex-flow: column-reverse without the order property assigned to each div, if you are so inclined against verbose CSS. The same demo restrictions apply; view this demo in full screen and resize the browser window accordingly.
.container div {
width: 100px;
height: 50px;
display: inline-block;
}
.one { background: red; }
.two { background: orange; }
.three { background: yellow; }
.four { background: green; }
.five { background: blue; }
#media screen and (max-width: 531px) {
.container { display: flex; flex-flow: column-reverse; }
}
<div class="container">
<div class="one">I'm first</div>
<div class="two">I'm second</div>
<div class="three">I'm third</div>
<div class="four">I'm fourth</div>
<div class="five">I'm fifth</div>
</div>
It's worth pointing out that flex-flow is a shorthand property encompassing both flex-direction and flex-wrap properties.
The result I'm looking for is one big block on the left, and then four small blocks on the right, and everything aligns.
I managed to do this in this fiddle but my solution has a couple of problems:
- it's not very clean in terms of code
- it's not responsive
HTML:
<div class="wrapper">
<div class="box big">ONE</div>
<div class="med-wrapper">
<div class="row-1">
<div class="box medium">TWO</div>
<div class="box medium">THREE</div>
</div>
<div class="row-2">
<div class="box medium">FOUR</div>
<div class="box medium">FIVE</div>
</div>
</div>
</div>
CSS:
.wrapper {
display: flex;
flex-direction: row;
flex-flow: row wrap;
justify-content: space-around;
height: 200px;
}
/* #media screen and (max-width: 768px) {
flex-direction: column
} */
.box {
background: #09f;
color: white;
padding: 1em;
margin: 5px;
text-align: center;
}
.big {
flex: 5;
}
.medium {
flex: 5;
height: 100px;
}
.med-wrapper {
display: flex;
}
Also, you might notice that I have set the flex on both .big and .medium to 5, because I want the total width of the big box and the total width of two medium boxes to be equal, but it didn't work.
Is there a better way to do this?
It's tricky to have everything to align without getting into a lot of constraints, but using flexbox wrapping in the column direction on the right part could work.
Here's a quick version that uses a flex-flow: column wrap on the right part (.med-wrapper) and gets rid of the wrapper element on the two column wrappers inside it -
<div class="wrapper">
<div class="box big">
ONE
</div>
<div class="med-wrapper">
<div class="box medium">TWO</div>
<div class="box medium">THREE</div>
<div class="box medium">FOUR</div>
<div class="box medium">FIVE</div>
</div><!-- /.med-wrapper -->
</div><!-- /.wrapper -->
...and then the CSS:
body {
font-family: 'calibri', sans-serif;
margin: 0;
}
.wrapper {
display: flex;
justify-content: space-around;
height: 200px;
}
.box {
background: #09f;
color: white;
padding: 1em;
margin: 0 5px;
text-align: center;
box-sizing: border-box;
}
.big {
flex: 1;
height: 100%;
}
.med-wrapper {
flex: 1;
display: flex;
height: 100%;
flex-flow: column wrap;
justify-content: space-between;
overflow: auto;
}
.medium {
/* exact sizing for the medium boxes (i.e. get it from main sizing.) */
flex: 0 0 auto;
/* adjust for margins: */
width: calc(50% - 10px);
height: calc(50% - 5px);
}
/* some theoretical adjustments for smaller screens */
#media screen and (max-width: 768px) {
/* switch the wrapper to column dir, and remove fixed height. */
.wrapper {
flex-direction: column;
height: auto;
}
/* just a min height for demo purposes. */
.big {
min-height: 200px;
}
/* Now we need to re-set a height on this one, if we
want to keep the 2x2 square thing. */
.med-wrapper {
margin-top: 10px;
height: 200px;
}
}
Live demo at http://jsbin.com/kasez/5/edit
I've used calc()for the size calculations to counter margins, but hey, if you're already depending on flexbox, you probably need a fallback anyway. :-)
It should work with just the one explicit height on the .wrapper element, but the rest of the items should adjust accordingly - the downside is that overflow handling gets hard.
This is, incidentally, the type of "2D" situation (vs flexbox's 1D) that Grid Layout is meant to help with, but it'll be a while before that is a viable option.