I come from a heavy div/float background to build responsive sites (e.g. Bootstrap 3, Foundation) and used Flex box briefly but have been attempting to use Grid everywhere since it's been really great at solving a number of problems. I seem to run into "simple" problems like this all too often and feel like I'm missing some basics, and can't find the answer in docs. Anyways, to the code.
Given a grid setup like so:
display: grid;
grid-auto-columns: max-content;
grid-auto-flow: column;
the content doesn't wrap to a new row once it's filled the width of its parent element. Ideally, I'd be able to have it auto-wrap without pre-defining exact pixel measurements such as grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));. This doesn't seem to work for my needs – I'd have to define multiple grid-template-columns measurements for different viewports, and know what a good width is for the items inside the columns. I'd much rather say grid-auto-columns: max-content; and then have items simply wrap to a new line.
Is this possible with grid? What am I missing/misunderstanding?
See Codepen with a full example demonstrating the problem: https://codepen.io/csdv/pen/OrbrzJ
I don't see how this is possible with the current iteration of CSS Grid.
As you've already discovered, you would at least need to define a fixed minimum width on the columns, in order to force a wrap at some point.
Unfortunately, with automatic repetitions, the minimum length cannot be auto, min-content or max-content alone, because that is forbidden in the specification.
Here's as close as you can get with Grid, as far as I can tell:
.btn-tabs {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(75px, max-content));
width: 20rem;
}
/* original demo styles */
.btn {
font-family: "Arial", sans-serif;
border-bottom: 4px solid #77aaee;
color: #77aaee;
padding: .6rem;
text-decoration: none;
}
<div class="btn-tabs">
<a class="btn" href="#">Button 1</a>
<a class="btn" href="#">Button 2</a>
<a class="btn" href="#">Button 3</a>
<a class="btn" href="#">Button 4</a>
<a class="btn" href="#">Button 5</a>
<a class="btn" href="#">Button 6</a>
</div>
Flexbox may be a good alternative, as it seems to work with your requirements:
.btn-tabs {
display: flex;
flex-wrap: wrap;
width: 20rem;
}
/* original demo styles */
/* notice no width defined on flex items, but they wrap anyway */
.btn {
font-family: "Arial", sans-serif;
border-bottom: 4px solid #77aaee;
color: #77aaee;
padding: .6rem;
text-decoration: none;
}
<div class="btn-tabs">
<a class="btn" href="#">Button 1</a>
<a class="btn" href="#">Button 2</a>
<a class="btn" href="#">Button 3</a>
<a class="btn" href="#">Button 4</a>
<a class="btn" href="#">Button 5</a>
<a class="btn" href="#">Button 6</a>
</div>
Spec the grid dim in %, like:
grid-template-columns: 25% 25% 25% 25%;
or
grid-template-columns: 25% auto auto auto;
The text will auto wrap inside the grid element defined as a %...
Related
I want to create the same layout as on this page https://open.spotify.com/genre/made-for-x. How to want the playlist elements to shrink until they reach 100px and then to wrap and when the window is expanding to grow until they reach 200px and then to unwrap.
All you need to achieve this layout is CSS Grid. You don’t need media queries.
CSS Grid has this awesome property grid-template-columns which lets you define a fixed or dynamic number of columns.
Use repeat() with a value of auto-fit inside of grid-template-columns to say you want as many columns as will fit into the grid container.
Use minmax(100px, max-content) to say that your grid columns should be at least 100px, but never more than the max-content size of the elements inside the grid.
Then, set max-width: 200px on your image elements, which will effectively determine that max-content size, because the images are sitting inside the grid.
Here’s a working example:
:root {
background-color: #111;
}
body {
color: white;
}
ul {
list-style-type: none;
padding: 0;
}
.grid-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(100px, max-content));
gap: 24px;
}
.grid-item {
background-color: #333;
display: flex;
flex-direction: column;
}
.playlist-image {
max-width: 200px;
}
<ul class="grid-container">
<li class="grid-item">
<img
class="playlist-image"
src="https://picsum.photos/id/237/400"
alt="Doggy"
/>
<h3 class="playlist-name">Discover Weekly</h3>
</li>
<li class="grid-item">
<img
class="playlist-image"
src="https://picsum.photos/id/237/400"
alt="Doggy"
/>
<h3 class="playlist-name">Daily Mix 1</h3>
</li>
<li class="grid-item">
<img
class="playlist-image"
src="https://picsum.photos/id/237/400"
alt="Doggy"
/>
<h3 class="playlist-name">Daily Mix 2</h3>
</li>
<li class="grid-item">
<img
class="playlist-image"
src="https://picsum.photos/id/237/400"
alt="Doggy"
/>
<h3 class="playlist-name">Release Radar</h3>
</li>
<li class="grid-item">
<img
class="playlist-image"
src="https://picsum.photos/id/237/400"
alt="Doggy"
/>
<h3 class="playlist-name">Family Mix</h3>
</li>
</ul>
You may create specific css for each screen size using #media.
Have a look at https://developer.mozilla.org/fr/docs/Web/CSS/#media to learn how to use them.
I'm trying to create two rows of buttons, 3 on the top and 4 on the bottom to sit centred on the page
[Image showing what I am trying to do][1] [1]: https://i.stack.imgur.com/HgVLS.jpg
I've managed to get the two rows, however when i try and centre them on the page by adding:
display: flex; justify-content: center;
I loose the gap around each of the buttons - I can't work out where to add the padding to give a consistent space between each button!
I was also hoping for the buttons to be mobile responsive and wrap on smaller screens. However I can't seem to figure this out either!
Would really appreciate any help.
.jd-btn {
padding: 10px 35px;
border: solid 1px red;
display: inline-block;
text-align: center;
font-size: 1.6rem;
}
.jd-btn:hover,
.jd-btn:focus {
cursor: pointer;
background-color: red;
color: #fff;
}
<div style="display: flex; justify-content: center;">
<a class="jd-btn">Button 1</a>
<a class="jd-btn">Product info 2</a>
<a class="jd-btn">Button 3</a><br />
</div>
<div style="display: flex; justify-content: center;">
<a class="jd-btn">Account info 4</a>
<a class="jd-btn">Product info 5</a>
<a class="jd-btn">Help 6</a>
<a class="jd-btn">Button 7</a>
</div>
</div>
I come from a heavy div/float background to build responsive sites (e.g. Bootstrap 3, Foundation) and used Flex box briefly but have been attempting to use Grid everywhere since it's been really great at solving a number of problems. I seem to run into "simple" problems like this all too often and feel like I'm missing some basics, and can't find the answer in docs. Anyways, to the code.
Given a grid setup like so:
display: grid;
grid-auto-columns: max-content;
grid-auto-flow: column;
the content doesn't wrap to a new row once it's filled the width of its parent element. Ideally, I'd be able to have it auto-wrap without pre-defining exact pixel measurements such as grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));. This doesn't seem to work for my needs – I'd have to define multiple grid-template-columns measurements for different viewports, and know what a good width is for the items inside the columns. I'd much rather say grid-auto-columns: max-content; and then have items simply wrap to a new line.
Is this possible with grid? What am I missing/misunderstanding?
See Codepen with a full example demonstrating the problem: https://codepen.io/csdv/pen/OrbrzJ
I don't see how this is possible with the current iteration of CSS Grid.
As you've already discovered, you would at least need to define a fixed minimum width on the columns, in order to force a wrap at some point.
Unfortunately, with automatic repetitions, the minimum length cannot be auto, min-content or max-content alone, because that is forbidden in the specification.
Here's as close as you can get with Grid, as far as I can tell:
.btn-tabs {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(75px, max-content));
width: 20rem;
}
/* original demo styles */
.btn {
font-family: "Arial", sans-serif;
border-bottom: 4px solid #77aaee;
color: #77aaee;
padding: .6rem;
text-decoration: none;
}
<div class="btn-tabs">
<a class="btn" href="#">Button 1</a>
<a class="btn" href="#">Button 2</a>
<a class="btn" href="#">Button 3</a>
<a class="btn" href="#">Button 4</a>
<a class="btn" href="#">Button 5</a>
<a class="btn" href="#">Button 6</a>
</div>
Flexbox may be a good alternative, as it seems to work with your requirements:
.btn-tabs {
display: flex;
flex-wrap: wrap;
width: 20rem;
}
/* original demo styles */
/* notice no width defined on flex items, but they wrap anyway */
.btn {
font-family: "Arial", sans-serif;
border-bottom: 4px solid #77aaee;
color: #77aaee;
padding: .6rem;
text-decoration: none;
}
<div class="btn-tabs">
<a class="btn" href="#">Button 1</a>
<a class="btn" href="#">Button 2</a>
<a class="btn" href="#">Button 3</a>
<a class="btn" href="#">Button 4</a>
<a class="btn" href="#">Button 5</a>
<a class="btn" href="#">Button 6</a>
</div>
Spec the grid dim in %, like:
grid-template-columns: 25% 25% 25% 25%;
or
grid-template-columns: 25% auto auto auto;
The text will auto wrap inside the grid element defined as a %...
I have the following HTML code:
<span class="container">
<span id="item1" class="item">
<button class="removeitem"></button>
<span class="text"></span>
</span>
<span id="item2" class="item">
<button class="removeitem"></button>
<span class="text"></span>
</span>
<span id="item3" class="item">
<button class="removeitem"></button>
<span class="text"></span>
</span>
</span>
Imagine the #item3 extends .container, but overflow is hidden. How can I achieve that the elements inside are still visible and will continue in the following row?
I tried the following (in Sass-syntax):
.container
display: flex
justify-content: flex-start
flex-wrap: wrap
But #item3 will just appear on the next row.
I tried making everything display: inline, but then I can not assign any height-properties.
I attached an image of what I want to achieve.
This is what the layout should look like. #item3 continues in the next row:
What you are asking is not technically possible unless you use the natural wrapping of text as in this example:
.item {
display: inline;
background: yellow;
margin-right: 5px;
border: 2px solid green;
line-height: 2;
}
Fiddle:
https://jsfiddle.net/658tdurx/1/
I have the following li item:
<li>
<span style='float:left; background-color:red'>a</span>
<span style='float:left; background-color:green'>b</span>
</li>
I'd like the span on the right to fill whatever width is remaining in its parent li. Is there a way to do that?
Thanks
You don't want to float each of them left, only the first one, and then make the second one display in block mode:
<li>
<span style="float:left; background-color:red">a</span>
<span style="display: block; background-color:green">b</span>
</li>
Looked for the same solution, but found only this which worked great for me:
<li>
<span style='display: table-cell; background-color:red'>a</span>
<span style='display: table-cell; width: 100%; background-color:green'>b</span>
</li>
All you need is just using table-cell displaying and set filler span width to 100%. All other solutions I've tried didn't work for me as expected.
Don't float the second one, and make it display:block.
http://jsfiddle.net/ymAt5/
You can use the grid layout:
<li class="my-grid">
<span class="left">a</span>
<span class="right">b</span>
</li>
And the css :
.my-grid {
display: grid;
grid-template-columns: max-content auto;
}
.left{
background: red;
}
.right{
background: blue;
}
Play with the grid-template-columns property so it suits your needs.
https://jsfiddle.net/c9j3ok7u/