I have a responsive layout set up for 3 columns. In each column is a product that we are trying to sell. Sometimes there could be 3 items, 2 items and 1 item. Currently when I remove 1 item it will display on 2/3 of the page and leave the 1/3 empty. How do I create it so that when there are 2 or 1 item being displayed for them to be centered and they would have a max-width of 640px?
/* -------- HTML ------------*/
<div class="item">Item1</div>
<div class="item">Item1</div>
<div class="item">Item1</div>
/* -------- CSS ------------*/
.item {
display: inline;
float: left;
width: 33.33%;
}
With flexbox, the container will fill 100% of the space based on how many items you have.
HTML
<div class="flex-row">
<div class="item">Item1</div>
<div class="item">Item2</div>
<div class="item">Item3</div>
</div>
<div class="flex-row">
<div class="item">Item1</div>
<div class="item">Item2</div>
</div>
<div class="flex-row">
<div class="item">Item1</div>
</div>
CSS
.flex-row {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
}
.item {
flex: 1;
}
Here is an example
A flex box would better suit your need. Remove/add item to see how the columns adapt to your new content:
.container{
display: flex;
}
.item{
flex-grow: 1;
background-color: red;
border: 1px solid black;
}
<div class="container">
<div class="item">Item1</div>
<div class="item">Item2</div>
<div class="item">Item3</div>
</div>
Related
Let's say I have a flex container, I want to be display between 1 and 3 items within.
I would like the items to be:
By default 1/3 of the width of the container (even if there's only 1 item)
If one of the item's text content expands slightly beyond the 33% width, I'd like that item to try and expand if it can (i.e. by one of the other items shrinking).
Justified using flex-start
.container {
display: 'flex';
flex-direction: 'row';
background-color: 'red';
width: '100%';
justify-content: 'flex-start';
}
.item {
flex: 1;
border: 1px solid red;
flex-wrap: 'no-wrap';
}
<div class="container">
<div class="item">blahhhhhhhhhhhhhhhhhhhhhhhhhh</div>
<div class="item">blahhh</div>
<div class="item">blahhh</div>
</div>
<div class="container">
<div class="item">I should take up 1/3</div>
</div>
The above works for the 3 item case, however when a singular item is placed there it expands to fill the space.
Is this possible?
You can use CSS-Grid for that.
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
margin-bottom: 1em;
}
.item {
height: 50px;
border: 1px solid red;
}
.item.wide {
width: 250px;
}
<div class="container">
<div class="item wide"> I'm wider than 1/3</div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="container">
<div class="item"></div>
</div>
<div class="container">
<div class="item"></div>
<div class="item"></div>
</div>
I want to make a responsive css grid that looks like this:
box | box | box
b o x | b o x
b o x | b o x
and then when the screen size gets small enough, all of the columns collapse into a single column with each box on its own row.
Is this possible?
Edit:
For anyone who has this issue, changing the number of columns via media query from 6 to 1 was not working. However, I had the idea to make all of the items span 6 columns at the break point and that worked perfectly. This is an addition to the answer given by lawrence-witt and paulie-d.
By using a SIX column grid
.item {
height: 3em;
border: 2px solid green;
}
.container {
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-gap: 4px;
width: 90%;
margin: 1em auto;
}
.item:nth-child(1),
.item:nth-child(2),
.item:nth-child(3) {
grid-column: span 2
}
.item:nth-child(4),
.item:nth-child(5) {
grid-column: span 3;
}
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
After that it's just a matter of adding a media query to collapse the grid to a single column at the appropriate breakpoint,
Here is one way to do it using the nth-child feature. To make the grid responsive you simply add a media query that changes the styling of cells and grid at a certain screen width.
.grid {
display: grid;
grid-template-columns: repeat(6, 1fr);
}
.cell {
border: 1px solid black;
grid-column: span 3;
}
.cell:nth-child(1),
.cell:nth-child(2),
.cell:nth-child(3){
grid-column: span 2;
}
<div class="grid">
<div class="cell">One</div>
<div class="cell">Two</div>
<div class="cell">Three</div>
<div class="cell">Four</div>
<div class="cell">Five</div>
<div class="cell">Six</div>
<div class="cell">Seven</div>
</div>
By using CSS flex layout and CSS media query you can achieve your need. See the below code, if the screen size reduced to 600px then it will change to single column layout.
.container {
display: flex;
width: 100%;
justify-content: space-between;
flex-direction: row;
margin-bottom: 10px;
}
.three-box-row > div {
width: 33%;
height: 50px;
}
.two-box-row > div {
width: 49%;
height: 50px;
}
#media only screen and (max-width: 600px) {
.container {
flex-direction: column;
}
.container > div {
width: 100%;
}
}
<body>
<div class="three-box-row container">
<div style="background-color: red;">Box 1</div>
<div style="background-color: green;">Box 2</div>
<div style="background-color: blue;">Box 3</div>
</div>
<div class="two-box-row container">
<div style="background-color: red;">Box 1</div>
<div style="background-color: green;">Box 2</div>
</div>
<div class="two-box-row container">
<div style="background-color: green;">Box 1</div>
<div style="background-color: blue;">Box 2</div>
</div>
</body>
I want to use flex to make a responsive section with static items aligned right on first row. The static items will occupy variable space on the first row (the static items will be different size in different layout thus it is variable space), the other items should avoid overlap the static items and auto wrap to second row when first row do not have enough space.
Expected result:
Screen width: 768px
|---------------------------------------------------------------------|
|[Item 1] [Item 2] [Item 3] [Static Item 1] [Static Item 2]|
|---------------------------------------------------------------------|
Screen Width: 320px
|-------------------------------------------|
|[Item 1] [Static Item 1] [Static Item 2]|
|[Item 2] [Item 3] |
|-------------------------------------------|
I tried following code but the static item cannot cannot keep at first line
.flex {
display: flex;
border: 1px solid black;
flex-wrap: wrap;
}
.item {
display: inline-flex;
border: 1px solid blue;
margin: 5px;
white-space: nowrap;
}
.static {
margin-left: auto;
flex-wrap: nowrap;
display: inline-flex;
}
<div class="flex">
<div class="item">Dynamic Item 1</div>
<div class="item">Dynamic Item 2</div>
<div class="item">Dynamic Item 3</div>
<div class="static">
<div class="item">Static Item 1</div>
<div class="item">Static Item 2</div>
</div>
</div>
I have idea with float and use with inline-block if you didn't want flex style
Main factor is...
display:inline-block on item
float:right on static item
In this example you can resized div box to test responsive ; )
.container{
display:block;
border: 2px solid;
resize: both;
overflow: auto;
background-color: yellow;
}
.item{
display:inline-block;
background-color: blue;
margin: 10px 10px;
}
.item.static{
float:right;
}
<div class="container">
<div class="item static">item5</div>
<div class="item static">item4</div>
<div class="item">item1</div>
<div class="item">item2</div>
<div class="item">item3</div>
</div>
You could try to combine a flexbox with two inline-flexboxes. The outer flexbox will align both boxes inside to the edges. On smaller screens only the first one will wrap.
.wrapper {
display: flex;
justify-content: space-between;
}
.item {
display: inline-flex;
}
.static-items {
display: inline-flex;
justify-content: flex-end;
flex-wrap: nowrap;
}
.item {
width: 100px;
height: 20px;
margin: 2px;
background-color: orange;
}
<div class="wrapper">
<div class="items">
<div class="item">
Item 1
</div>
<div class="item">
Item 2
</div>
<div class="item">
Item 3
</div>
</div>
<div class="static-items">
<div class="item">
Static Item 1
</div>
<div class="item">
Static Item 2
</div>
</div>
</div>
<br/>
Try this
<section class="row">
<section class="group">
<item1 />
<item2 />
<item3 />
</section>
<section class="group">
<item4 />
<item5 />
</section>
</section>
CSS
.row{
display: flex;
justify-content: space-between
}
I am working on a responsive site in which the mobile/tablet view differs from the desktop view in the way it re-orders the DIVs.
Is there a way to write maintainable CSS that let's you re-organize the order of how HTML DIVs appear?
For example, the code below controls the order of how DIVs would appear on a desktop device:
<div class="container">
<div class="row1">
<div class="col1A">Sample content</div>
<div class="col2A">Sample content</div>
<div class="col3A">Sample content</div>
</div>
<div class="row2">
<div class="col1B">Sample content</div>
<div class="col2B">Sample content</div>
<div class="col3B">Sample content</div>
</div>
</div>
However, for mobile/tablet view, I want to display the DIVs in different order using CSS, like the example below:
Show row2, col2B
Then row1, col1A
Then row1, col3A
Then row2, col1B
Is this possible using CSS ?
As a proof-of-concept, you can use the flex CSS property to reorder how elements are visually rendered.
In your example, I had to keep the child elements within a single container
and then I could control the order using the order property.
If you want to hide some items on the small screen view, use display: none on the specific items.
Note: For a wide screen, you would need some CSS rules to get the items to look like two rows. (Please specify what you need.)
If you combine this with media queries, you can get a workable solution.
.container {
display: flex;
flex: center;
flex-direction: column;
align-items: center;
border: 1px dotted blue;
}
.container div {
text-align: center;
padding: 10px;
border: 1px dotted gray;
width: auto;
}
.col1A {
order: 2;
}
.col2A {
display: none;
}
.col3A {
order: 3;
}
.col1B {
order: 4;
}
.col2B {
order: 1;
}
.col3B {
display: none;
}
<div class="container">
<div class="row1 col1A">Sample content 1A</div>
<div class="row1 col2A">Sample content 2A</div>
<div class="row1 col3A">Sample content 3A</div>
<div class="row2 col1B">Sample content 1B</div>
<div class="row2 col2B">Sample content 2B</div>
<div class="row2 col3B">Sample content 3B</div>
</div>
If you want to simulate two rows of three elements, you can still use flex with some adjustments. The following may be helpful.
.container {
display: flex;
flex: center;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
border: 1px dotted blue;
padding: 20px 0;
}
.container .row1 {
margin-bottom: 20px;
}
.container div {
text-align: center;
padding: 10px;
border: 1px dotted gray;
flex-basis: calc(33% - 20px);
}
.col1B {
background-color: yellow;
}
<div class="container">
<div class="row1 col1A">Sample content 1A</div>
<div class="row1 col2A">Sample content 2A</div>
<div class="row1 col3A">Sample content 3A</div>
<div class="row2 col1B">Sample content 1B</div>
<div class="row2 col2B">Sample content 2B</div>
<div class="row2 col3B">Sample content 3B</div>
</div>
Set a screen size for mobile device detection in the css and add the following
#media screen and (max-width: SIZE) {
.row2{
display: flex; flex-flow: column;
}
.col1B{
order: 1;
}
.col2B{
order: 2;
}
.col3B{
order: 3;
}
}
And then add the classes to the DIVs
<div class="row2">
<div class="col1B">Sample content</div>
<div class="col2B">Sample content</div>
<div class="col3B">Sample content</div>
</div>
Change order: 1/2/3; to your needs.
I have two rows containing tree columns each. On a Responsive breakpoint, I'd like to switch to tree lines of two columns.
Due to the initial structure, this does not seem possible (I can only make 1 colum rows, or tree column rows, bot not two column rows).
No JS please...
How is this usually solved? DEMO HERE
CSS
.col {
float: left;
width: 33.33%;
background: red;
text-align: center;
}
#media (max-width:500px) {
.col {
width: 50%;
}
}
HTML
<div class="row" style="overflow:auto;">
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
</div>
<div class="row" style="overflow:auto;">
<div class="col">4</div>
<div class="col">5</div>
<div class="col">6</div>
</div>
Try this code
.contain {
display: flex;
flex-wrap: wrap;
}
.col {
flex: 1;
min-width: 33%;
}
#media (max-width:500px) {
.col {
min-width: 50%;
}
}
<div class="contain">
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
<div class="col">4</div>
<div class="col">5</div>
<div class="col">6</div>
</div>