I am trying to create a responsive grid with flexbox:
On large screens, there should be three columns in one row
On smaller screens, just two rows or one
My code so far:
.grid {
display: flex;
flex-wrap: wrap;
}
.gridColumn {
flex: 1 1 0px;
background-color: lightblue;
min-width: 200px;
}
<div class="grid">
<div class="gridColumn">
<p>first column</p>
</div>
<div class="gridColumn">
<p>second column</p>
</div>
<div class="gridColumn">
<p>third column</p>
</div>
</div>
Now, I would like to set margins only between the columns (not on the sides of the grid as well), which should also behave correctly when the screen is resized. Does anybody know of a way to achieve this?
You can add a margin to the grid items...
.gridColumn {
margin: $margin;
}
... which is then offset by its container.
.grid {
margin: -$margin;
}
To avoid overflow, you could apply overflow-x: hidden to the body.
Codepen example
It's crashed on this part of code
.gridColumn + .gridColumn {
margin-left: 20px;
}
You should to try use media query and set margin-left: 0; on small screens.
Above part of code is still working because flex-wrap only changing the position of the "third column", that column still have "sister" before and margin-left is working.
Related
currently I’m struggling with positioning these 3 text columns just like in picture. Each column contains 3 patagraphs.
Problem is, paragraph’s width is not equal, so grid-template-columns:repeat(3, 1fr) is not ideal solution because second and third paragraph will have unnecessary big white-space and that’s the problem when responsibility comes in. (Layout will break very soon because of that white-space).
I’ve tried min-content or max-content atributes but still I can’t figure it out, so it will look just as in the picture.
So goal is to align columns and paragraphs in it just like in the picture but without unwanted whitespace so work with responsibility will be easier.
Is there any better solution for it?
I have tried my best, here’s codepen
Thank you!
You can use minmax in your grid-template-column property, minmax(5rem, 10rem) minmax(3rem, 5rem) auto;, this will set the minimum width of the first column to 5rem and the maximum width to 10rem, the second to min of 3rem and max of 5rem, then the last columns width will be the width of its content => auto.
css-grid-layout-minmax ~ MDN
.card {
background: silver;
padding: 0 1rem;
border-radius: 12px;
}
.column {
display: grid;
grid-template-columns: minmax(5rem, 10rem) minmax(3rem, 5rem) auto;
justify-content: flex-start;
}
p:nth-of-type(3),
p:nth-of-type(4),
p:nth-of-type(2) {
text-align: right;
}
p + p {
margin-left: 1rem;
}
<div class="card">
<div class="column-wrapper">
<div class="column">
<p>lorem:</p>
<p>282726€</p>
<p>28%</p>
</div>
<div class="column">
<p>lorem ipsum:</p>
<p>287€</p>
<p>10%</p>
</div>
<div class="column">
<p>lorem:</p>
<p>19118€</p>
</div>
</div>
</div>
This question already has answers here:
Targeting flex items on the last or specific row
(10 answers)
Closed 2 years ago.
I'm creating a nav menu using flex. I want all of the items in my menu to display in a single row when the screen is wide enough to support that, and to snap to two rows of items when it needs to wrap. I have this mostly working:
.content {
width: 400px;
height: 150px;
border: thin solid black;
}
.outer {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.inner {
display: flex;
justify-content: space-around;
flex-grow: 1;
}
span {
font-size: 24pt;
}
<div class="content">
<div class="outer">
<div class="inner">
<span>one</span>
<span>two</span>
<span>three</span>
</div>
<div class="inner">
<span>four</span>
<span>five</span>
<span>six</span>
</div>
</div>
</div>
CodePen here.
This works perfectly when the page is wide enough:
And it works mostly perfectly when the page is narrow (try changing the width of .content to 250px):
However, now I'm trying to make it so the items in each row line up with each other. I'm going for something like this:
I've tried every combination of flex-grow, flex-shrink, and justify-content that I can think of, but I can't get the items to align.
I know I could probably use a media query and swap out the content for a grid when the window gets too narrow, but I'd like to simplify this as much as possible. Is there a way to align the children of two flex divs?
Alternatively, is there a way to use a grid layout that shows as 1 row until it needs to wrap, and then it shows as 2 rows?
It causes by span width.
if span width not fixed, span will have dynamic width;
set width on span;
Try this
Add to te span
span {
flex: 33%;
}
Or change the porcent acording to the amount of items the div has
I'm trying to create a four column layout where each column grows and shrinks with the size of the window, but each column has a minimum width and when the window is too small for all four columns to fit in a single row, it transitions to a single column with each section taking up the full width.
I've been unable to do this with either flex-box or CSS grid. And I'd like to do this without a media query. Using a media query would solve the issue pretty easily, but I don't like them!
.col {
width: 100%;
display: flex;
flex-wrap: wrap;
}
.section {
margin: 10px 0px 0px 10px;
min-width: 250px;
height: 400px;
background-color: gray;
flex: auto;
}
<div class="col">
<div class="section">
</div>
<div class="section">
</div>
<div class="section">
</div>
<div class="section">
</div>
</div>
And a codepen: https://codepen.io/WriterState/pen/oRKxMj
Media queries are great, but they are not always a viable substitute for container queries (which sadly do not exist).
A horizontal to vertical layout switch can be achieved using CSS calc when you know how many columns you will have.
.child{
min-width: 25%; /* 100% divide number columns */
max-width: 100%;
width: calc((50rem - 100%) * 1000); /* Replace 50rem with size of .parent when you want switch to happen */
}
The width is calculated as your desired breakpoint minus the width of the parent container. This either generates a negative number and the min-width is applied, or a large number in which case the max-width takes over.
If you are using flex-box then width can also be flex-basis.
Source: https://www.sitepoint.com/responsive-css-patterns-without-media-queries/
I have the following HTML and CSS layout:
html {
position: relative;
min-height: 100%;
}
body {
/* Margin bottom by footer height */
margin-bottom: 100px;
}
.col-md-6 {
display: flex;
justify-content: center;
}
.container_flex {
display: flex;
align-items: center;
justify-content: center;
/* vh refers to viewport height. Very useful! */
height: 100vh;
width: 100%;
}
<div class="container-fluid">
<div class="container_flex">
<div class="row">
<div class="col-md-6 col-xs-12" style="border:solid">
<h1>Column 1</h1>
</div>
<div class="col-md-6 col-xs-12" style="border:solid">
<h1>Column 2</h1>
</div>
</div>
</div>
</div>
Which provides the following result:
Bootply
My aim of using Flexbox is to vertically center the contents of "row" inside the container-fluid. However, this results in the columns adopting a compressed look when in desktop mode. When in mobile view, the columns do stack as expected. I would be grateful if someone could explain why this compressed/stubby look comes about?
In contrast, if I remove the row class, this stubby compressed look no longer is brought about as shown:
Bootply
However, the columns no longer stack when in mobile view. Is there any way that I can rectify this?
If anyone has any tips/pointers on how to effectively use FlexBox with Bootstrap to vertically and horizontally center in a more effective way than what I have attempted here, I would be very grateful.
When you remove the row element the .col elements become your flex-items. In order to get flex-items to wrap in a flex container you need to use the flex-wrap property. However, I don't think removing the row element and using flex-wrap is what you really want.
With regards to your question. The reason it looks stubby in your first example is because you are making the row element your 'flex-item'. The width of the row item then sizes to its contents because you have not set the flex property which controls its size. Once you set the flex property properly then you will see the desired results:
.container_flex {
display: flex;
align-items: center;
justify-content:center;
/* vh refers to viewport height. Very useful! */
height: 100vh;
width: 100%;
}
.row {
flex: 1;
}
<div class="container-fluid">
<div class="container_flex">
<!-- Note that if using Flexbox, then do not need to wrap col- in row class but then does not stack columns on mobile... use #media? -->
<div class="row">
<div class="col-md-6 col-xs-12" style="border:solid">
<h1>Column 1</h1>
</div>
<div class="col-md-6 col-xs-12" style="border:solid">
<h1>Column 2</h1>
</div>
</div>
</div>
</div>
Here is a brief explanation why: flex:1 is a shortcut property that sets three separate flex-item properties to:
flex-grow: 1; If the size of the flex-item is smaller than available space within the flex container then setting this to a value greater than 0 makes the item stretch to fill the available space. If there are multiple flex-items in the same container they grow to share the available space in proportion to the value of their flex-grow property.
flex-shrink: 1; If the size of the flex-item is larger than the available space within the flex container then setting this to a value greater than 0 makes the item shrink to fit the available space. If there are multiple flex-items in the same container they will shrink to share the available space in proportion to the value of their flex-shrink property.
flex-basis: 0%; Defines the starting size of the element before being "flexed".
For general informanton on using flex-box take a look at this article over at css tricks by Chris Coyier; he does a great job explaining how flex-box works.
If you are looking for information on using bootstrap and flex-box together I recommend reading this article as well!
I hope this helps.
you need to give flex:1 to .row which it shorthand for flex-grow, flex-shrink and flex-basis combined. Default is 0 1 auto, using flex:1 means it will be 1 1 0
html {
position: relative;
min-height: 100%;
}
body {
/* Margin bottom by footer height */
margin-bottom: 100px;
}
.row {
flex: 1
}
.col-md-6 {
display: flex;
justify-content: center;
}
.container_flex {
display: flex;
align-items: center;
justify-content: center;
/* vh refers to viewport height. Very useful! */
height: 100vh;
width: 100%;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<div class="container-fluid">
<div class="container_flex">
<div class="row">
<div class="col-md-6 col-xs-12" style="border:solid">
<h1>Column 1</h1>
</div>
<div class="col-md-6 col-xs-12" style="border:solid">
<h1>Column 2</h1>
</div>
</div>
</div>
</div>
You may also use the flex built-in library from bootsrap (it will also be responsive):
http://v4-alpha.getbootstrap.com/layout/flexbox-grid/#responsive-flexbox
.col-md-6.col-xs-12{border:solid}/* CSS neede cause border are not set by default in bootsrap :) */
<link href="http://v4-alpha.getbootstrap.com/assets/css/docs-flexbox.min.css" rel="stylesheet"/>
<link href="http://v4-alpha.getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
<p>To see cols side by side, run snippet in full page mode and reduce it down to average 720px width to see col stacking </p>
<div class="row">
<div class="col-md-6 col-xs-12" >
col 1
</div>
<div class="col-md-6 col-xs-12" >
col 2
</div>
</div>
</div>
I am making a fairly simple responsive website. I have a logo div that keeps the logo centered on small screens, and to the left on big screens. Everything is working how I want it to, (try resizing the jsfiddle) except that I want the logo div to scale down to it's min-width before the links wrap to the next line. I'm not sure how to word this, but I want the logo div to resize based on if the links are pushing it (if they have enough room). When it reaches it's min-width, then the links should wrap. Not sure if this is possible, but I figured I'd ask anyway.
Here is the jsfiddle.
The html:
<div class="header">
<div class="logo">logo</div>
<div class="link">link one</div>
<div class="link">link two</div>
<div class="link">link three</div>
</div>
The css:
.header {
text-align: center; /* Centers the logo text, and centers the links between the logo div and the other side of the page.*/
}
.logo {
max-width: 300px;
min-width: 100px;
width: 100%; /* It is always the min-width without this*/
background-color: red;
display: inline-block;
float: left;
}
.link {
display: inline-block;
background-color: green;
}
I hope I was clear, I'm still learning. Let me know if I need to add any more details.
I went looking some more and found flexboxes. Got them to do exactly what I wanted.
http://jsfiddle.net/3525C/10/
My new HTML:
<div class="header">
<div class="logo">logo</div>
<div class="nav">
<div class="link">link one</div>
<div class="link">link two</div>
<div class="link">link three</div>
</div>
</div>
and CSS:
.header {
text-align: center;
display: flex;
flex-flow: row wrap;
}
.logo {
flex: 1 0 auto;
min-width: 100px;
background-color: red;
}
.nav {
flex: 1 1 auto;
background-color: lightgray;
text-align: center;
}
.link {
display: inline-block;
background-color: green;
}
Thanks hexalys for helping me get it working.
The only real thing that responds the way you're talking is a table. Table cells have the capability of being flexible with their width.
You can use CSS to make this happen. It's a more modern display, so not all browsers (looking at you, older IE) will support it. But this should get you started: http://jsfiddle.net/mfvf8/
Here's what I added as a proof of concept:
.header
{
display: table;
width: 100%;
}
.header > div
{
display: table-cell;
}
.header .link
{
white-space: nowrap;
width: 1px;
}
I set the header to be displayed as a table, and gave it full width. I made all of the child divs act like a table cell. I made the links minimum width (1px) and said not to wrap whitespace. With regular divs, that would overflow. With table cells, that means it tries to be 1px wide but will expand to fit its content.
The rest of a table row's width will go evenly to whichever cells are left over that don't have a set width. In this case, it's the logo div. Then, as you shrink the window, it will slowly start to shrink the logo as needed.
You will need to tweak this to fit your design better. If you don't want your nav pushed all the way to the right like it is in the jsfiddle, you might need a "buffer" div to the far right, or different width settings, or a set max-width on the header div.