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.
Related
I'm creating a timeline in css that overflows if content is too long. I have text above and below the timeline where each segment is equal to the width of the text.
I've played around with both absolute and relative positioning.
The issue with absolute position is that I can't set the width of each segment to the text, which causes issues when the width of the viewport is smaller than the cumulative text.
The issue with relative position is that the text and the segment is all centered as a whole, which doesn't center the segment perfectly.
Before this I used margin-top and margin-bottom and set the segment to the parent element. The issue with this is that now my height has to be set manually since the height of the element is tied to the segment, and not the child text.
<div class="timeline">
<div class="segment">
<h1>title</h1>
<div class="line"></div>
<ul>
<li>list</li>
...
</ul>
</div>
...
</div>
.timeline
display flex
flex-wrap nowrap
align-items center
width 100%
.segment
flex auto
white-space nowrap
display flex
flex-direction column
.line
height 0.1rem
background-color black
I expect:
x x x
⬤⸻⬤⸻⬤⸻⬤
y y y
y
But I get this instead (roughly speaking):
x x x
⬤______⬤⸻⬤______⬤
y y y
y
I'm still not 100% sure how your code is set up but I believe the issue is with the uneven list items. This can happen when you use display flex with an uneven amount of items in a ul element.
I changed the display for .timeline from display: flex to display: inline-block, which is safer for displaying uneven lists, as well as the display for .segment from display: flex to display: inline-flex.
You should also consider using inline-flex for items that you want to have a display of flex but remain inline.
Please see the snippit below.
.timeline{
display: inline-block;
align-items: center;
width: 100%;
}
.segment{
width:200px;
display: inline-flex;
white-space: nowrap;
flex-direction: column;
}
.line{
height: 0.1rem;
background-color: black;
}
.timeline > div:nth-child(even) > .list {
position: absolute;
}
/* UNCOMMENT BELOW TO SEE ORIGINAL CSS*/
/* .timeline{
display: flex;
flex-wrap: nowrap;
align-items: center;
width: 100%;
}
.segment{
flex: auto;
white-space: nowrap;
display: flex;
flex-direction: column;
}
.line{
height: 0.1rem;
background-color: black;
} */
<div class="timeline">
<div class="segment">
<h1>title</h1>
<div class="line"></div>
<ul class='list'>
<li>x</li>
<li>x</li>
</ul>
</div>
<div class="segment">
<h1>title</h1>
<div class="line"></div>
<ul class='list'>
<li>y</li>
<li>y</li>
<li>y</li>
</ul>
</div>
<div class="segment">
<h1>title</h1>
<div class="line"></div>
<ul class='list'>
<li>y</li>
</ul>
</div>
</div>
As you can see, I added
.timeline > div:nth-child(even) > .list {
position: absolute;
}
To give you a quick fix for displaying every second list item above the lines, keeping the odd lists below.
As you didn't provide all of your code I cannot make the replication exactly like your use case but the phenomenon is the same and this should help you achieve what you're looking for.
One thing you can do is to set align-items: start;. If need to center all that vertically in a container, you can wrap everything into a div that will be centered.
If you need to have different sized titles, you can set fixed line-height and margin.
.timeline {
display: flex;
flex-wrap: nowrap;
align-items: start;
width: 100%;
}
.segment {
flex: auto;
white-space: nowrap;
display: flex;
flex-direction: column;
}
.segment h1{
line-height: 38px;
margin: 21px 0;
}
.line {
height: 0.1rem;
background-color: black;
}
<div class="timeline">
<div class="segment">
<h1>title</h1>
<div class="line"></div>
<ul>
<li>list</li>
</ul>
</div>
<div class="segment">
<h1>title</h1>
<div class="line"></div>
<ul>
<li>list</li>
<li>list</li>
</ul>
</div>
<div class="segment">
<h1 style="font-size: 20px;">title</h1>
<div class="line"></div>
<ul>
<li>list</li>
<li>list</li>
<li>list</li>
</ul>
</div>
</div>
How to achieve a layout with similar properties to Pintrest?
Specifically:
Responsive layout where all pictures are the same width.
All pictures are contained in a single div. There are no multiple containers trying to replicate "columns", e.g. using flexbox.
The order of the layout is such that there are no gaps. For example, if the layout is two columns, and the pictures are of width, heights: [(100,400), (100,100), (100,400), (100,100), (100,400), (100,100)], the columns will be around the same height and not 1200 for the left and 400 for the right. The screenshots below illustrate this.
Here is a screenshot showing that all photos are in a single div container.
The responsive layout:
An example of the third bullet point: the dark shower picture went below the hanging seat picture and not the external house picture. This is because the hanging seat picture has a smaller height.
Similarly when the layout is two columns wide: the picture of the bedroom goes below the handing chairs because the hanging seat picture has a smaller height.
Although this post appears similar to CSS-only masonry layout, the solutions do not result in desired outcome:
Using #Oliver Joseph Ash solution results in:
grid-container {
display: flex;
flex-flow: column wrap;
align-content: space-between;
/* Your container needs a fixed height, and it
* needs to be taller than your tallest column. */
height: 960px;
/* Optional */
background-color: #f7f7f7;
border-radius: 3px;
padding: 20px;
width: 60%;
margin: 40px auto;
counter-reset: items;
}
grid-item {
width: 24%;
/* Optional */
position: relative;
margin-bottom: 2%;
border-radius: 3px;
background-color: #a1cbfa;
border: 1px solid #4290e2;
box-shadow: 0 2px 2px rgba(0, 90, 250, 0.05), 0 4px 4px rgba(0, 90, 250, 0.05), 0 8px 8px rgba(0, 90, 250, 0.05), 0 16px 16px rgba(0, 90, 250, 0.05);
color: #fff;
padding: 15px;
box-sizing: border-box;
}
<grid-container>
<grid-item>
<a href="https://g.foolcdn.com/image/?url=https%3A%2F%2Fg.foolcdn.com%2Feditorial%2Fimages%2F492452%2Fgettyimages-1014028076.jpg&w=700&op=resize">
<img src="https://g.foolcdn.com/image/?url=https%3A%2F%2Fg.foolcdn.com%2Feditorial%2Fimages%2F492452%2Fgettyimages-1014028076.jpg&w=700&op=resize">
</a>
</grid-item>
<grid-item>
<a href="https://image.jimcdn.com/app/cms/image/transf/none/path/sa716b1500dd60f05/image/ic839a74ed6a8a054/version/1519833130/image.jpg">
<img src="https://image.jimcdn.com/app/cms/image/transf/none/path/sa716b1500dd60f05/image/ic839a74ed6a8a054/version/1519833130/image.jpg">
</a>
</grid-item>
<grid-item>
<a href="https://c8.alamy.com/comp/AXBEXR/stock-photograph-of-a-asian-teen-with-a-trumpet-to-her-ear-AXBEXR.jpg">
<img src="https://c8.alamy.com/comp/AXBEXR/stock-photograph-of-a-asian-teen-with-a-trumpet-to-her-ear-AXBEXR.jpg">
</a>
</grid-item>
<grid-item>
<a href="https://thumbs.dreamstime.com/z/cyber-woman-orange-11363555.jpg">
<img src="https://thumbs.dreamstime.com/z/cyber-woman-orange-11363555.jpg">
</a>
</grid-item>
<grid-item>
<a href="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcThObqAcFeb4byMcwLVkU1JVMYonpavYmEukk9r3rqF2oBTnd1q">
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcThObqAcFeb4byMcwLVkU1JVMYonpavYmEukk9r3rqF2oBTnd1q">
</a>
</grid-item>
<grid-item>
<a href="https://www.demilked.com/magazine/wp-content/uploads/2018/03/5aaa1cce4180b-funny-weird-wtf-stock-photos-57-5a3bb7ba3c266__700.jpg">
<img src="https://www.demilked.com/magazine/wp-content/uploads/2018/03/5aaa1cce4180b-funny-weird-wtf-stock-photos-57-5a3bb7ba3c266__700.jpg">
</a>
</grid-item>
<grid-item>
<a href="https://static.boredpanda.com/blog/wp-content/uploads/2018/05/emilia-clarke-making-stock-photos-5-5b0801c7504b2__700.jpg">
<img src="https://static.boredpanda.com/blog/wp-content/uploads/2018/05/emilia-clarke-making-stock-photos-5-5b0801c7504b2__700.jpg">
</a>
</grid-item>
<grid-item>
<a href="https://static.boredpanda.com/blog/wp-content/uploads/2018/05/emilia-clarke-making-stock-photos-8-5b0801cd0f33d__700.jpg">
<img src="https://static.boredpanda.com/blog/wp-content/uploads/2018/05/emilia-clarke-making-stock-photos-8-5b0801cd0f33d__700.jpg">
</a>
</grid-item>
<grid-item>
<a href="https://www.atomix.com.au/media/2017/07/StockPhotoBanner.jpg">
<img src="https://www.atomix.com.au/media/2017/07/StockPhotoBanner.jpg">
</a>
</grid-item>
</grid-container>
Which makes the output look like:
Whereas #Michael_B solution:
grid-container {
display: grid;
grid-auto-rows: 50px;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(30%, 1fr));
}
grid-item {
display: flex;
align-items: center;
justify-content: center;
font-size: 1.3em;
font-weight: bold;
color: white;
}
img {
width: 200px;
}
<grid-container>
<grid-item>
<a href="https://g.foolcdn.com/image/?url=https%3A%2F%2Fg.foolcdn.com%2Feditorial%2Fimages%2F492452%2Fgettyimages-1014028076.jpg&w=700&op=resize">
<img src="https://g.foolcdn.com/image/?url=https%3A%2F%2Fg.foolcdn.com%2Feditorial%2Fimages%2F492452%2Fgettyimages-1014028076.jpg&w=700&op=resize">
</a>
</grid-item>
<grid-item>
<a href="https://image.jimcdn.com/app/cms/image/transf/none/path/sa716b1500dd60f05/image/ic839a74ed6a8a054/version/1519833130/image.jpg">
<img src="https://image.jimcdn.com/app/cms/image/transf/none/path/sa716b1500dd60f05/image/ic839a74ed6a8a054/version/1519833130/image.jpg">
</a>
</grid-item>
<grid-item>
<a href="https://c8.alamy.com/comp/AXBEXR/stock-photograph-of-a-asian-teen-with-a-trumpet-to-her-ear-AXBEXR.jpg">
<img src="https://c8.alamy.com/comp/AXBEXR/stock-photograph-of-a-asian-teen-with-a-trumpet-to-her-ear-AXBEXR.jpg">
</a>
</grid-item>
<grid-item>
<a href="https://thumbs.dreamstime.com/z/cyber-woman-orange-11363555.jpg">
<img src="https://thumbs.dreamstime.com/z/cyber-woman-orange-11363555.jpg">
</a>
</grid-item>
<grid-item>
<a href="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcThObqAcFeb4byMcwLVkU1JVMYonpavYmEukk9r3rqF2oBTnd1q">
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcThObqAcFeb4byMcwLVkU1JVMYonpavYmEukk9r3rqF2oBTnd1q">
</a>
</grid-item>
<grid-item>
<a href="https://www.demilked.com/magazine/wp-content/uploads/2018/03/5aaa1cce4180b-funny-weird-wtf-stock-photos-57-5a3bb7ba3c266__700.jpg">
<img src="https://www.demilked.com/magazine/wp-content/uploads/2018/03/5aaa1cce4180b-funny-weird-wtf-stock-photos-57-5a3bb7ba3c266__700.jpg">
</a>
</grid-item>
<grid-item>
<a href="https://static.boredpanda.com/blog/wp-content/uploads/2018/05/emilia-clarke-making-stock-photos-5-5b0801c7504b2__700.jpg">
<img src="https://static.boredpanda.com/blog/wp-content/uploads/2018/05/emilia-clarke-making-stock-photos-5-5b0801c7504b2__700.jpg">
</a>
</grid-item>
<grid-item>
<a href="https://static.boredpanda.com/blog/wp-content/uploads/2018/05/emilia-clarke-making-stock-photos-8-5b0801cd0f33d__700.jpg">
<img src="https://static.boredpanda.com/blog/wp-content/uploads/2018/05/emilia-clarke-making-stock-photos-8-5b0801cd0f33d__700.jpg">
</a>
</grid-item>
<grid-item>
<a href="https://www.atomix.com.au/media/2017/07/StockPhotoBanner.jpg">
<img src="https://www.atomix.com.au/media/2017/07/StockPhotoBanner.jpg">
</a>
</grid-item>
</grid-container>
Is a lot better but results in height overlapping pictures:
My recommendation would be to set up a few "span" classes and contrain the images/masonry-items to have a height that is a multiple of the smallest unit. This approach allows for a CSS only masonry, but we need to know what multiple of the smallest unit items are beforehand (e.g. while rendering the HTML) so we can apply these span classes that could look like this:
.grid-span-2 {
grid-row-end: span 2;
}
.grid-span-3 {
grid-row-end: span 3;
}
.grid-span-4 {
grid-row-end: span 4;
}
...
If this is not possible, the next best approach is to use a little JS to dynamically calculate the row-span based on an items height. The snippet below should give an idea of how to approach this.
The most important part is the following:
const sizeItems = () => {
// only trigger DOM repaint when necessary
if ( $('.grid-container')[0].style.gridAutoRows !== '1px' ) {
$('.grid-container')[0].style.gridAutoRows = '1px';
}
$('.grid-item > *').forEach(el => {
const height = Math.floor(el.getBoundingClientRect().height);
// only trigger DOM repaint when necessary
if ( el.parentElement.style.gridRowEnd !== `span ${height}` ) {
el.parentElement.style.gridRowEnd = `span ${height}`;
}
});
}
We need to wait for images to load before we can do that, and also do it again when the viewport is resized, that's basically the rest of the JS code.
What we're doing here is to get the real/true height of the content within a grid-item. I prefer to use a wrapper element inside each grid-item and use that to measure. Why?
a) There are properties from the grid-module that can mess with the actual height of the grid-item without you seeing it and can then lead to incorrect height-calculations.
b) With this approach we can't use grid-gap (because in this extreme case we are making 1px-rows for the most precise sizing) as it would mess up the cell-heights, so to still be able to have a gap, we can use this wrapper div as well and apply padding to it to imitate the grid-gap.
For the JS approach we set grid-auto-rows: 1px;, this gives us the most flexibility in terms of item height, as basically each grid-cell can be sized to fit its content exactly, note though that there can be some small glitches of 1px, most likely due to subpixel rendering...
// micro DOM helper, just for convenience
const $ = window.$ = function(a,b){return Array.prototype.slice.call(document.querySelectorAll(a, b));};
const sizeItems = () => {
// only trigger DOM repaint when necessary
if ( $('.grid-container')[0].style.gridAutoRows !== '1px' ) {
$('.grid-container')[0].style.gridAutoRows = '1px';
}
$('.grid-item > *').forEach(el => {
const height = Math.floor(el.getBoundingClientRect().height);
// only trigger DOM repaint when necessary
if ( el.parentElement.style.gridRowEnd !== `span ${height}` ) {
el.parentElement.style.gridRowEnd = `span ${height}`;
}
});
}
Promise.all($('img').map(img => {
return new Promise(resolve => {
img.onload = () => {
resolve();
}
img.onerror = () => {
resolve();
}
});
})).then(() => {
const emit = new Event('images');
window.dispatchEvent(emit);
});
window.addEventListener('images', function(e) {
console.log('onImagesLoaded');
sizeItems();
});
window.addEventListener('load', function(e) {
console.log('onLoad');
sizeItems();
});
window.addEventListener('resize', function(e) {
console.log('onResize');
sizeItems();
});
* {
box-sizing: border-box;
margin: 0;
}
body {
font-family: sans-serif;
}
.grid-container {
background: gold;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(calc(100%/3), 1fr));
grid-gap: 0; /* can't use grid gap! */
/* grid-auto-rows: auto; */
grid-auto-flow: dense;
/* if you don't want a gap on the outside of the grid when working with padding */
/* margin: -4px; */
}
#media screen and (max-width: 600px) {
.grid-container {
grid-template-columns: repeat(auto-fill, minmax(50%, 1fr));
}
}
#media screen and (max-width: 400px) {
.grid-container {
display: block;
}
}
.grid-item {
display: flex;
align-items: flex-start;
justify-content: center;
font-size: 1.3em;
font-weight: bold;
color: hsl(0,0%,14%);
}
.grid-gap {
/* if you need a grid-gap, apply padding to a wrapper element INSIDE the grid-item */
/* padding: 4px; */
overflow: hidden;
width: 100%;
}
.grid-item a,
.grid-item img {
display: block;
width: 100%; height: 100%;
}
.grid-item figcaption {
background: lightcoral;
color: white;
font-size: 14px;
font-style: italic;
padding: 4px 0;
text-align: center;
}
<div class="grid-container">
<div class="grid-item">
<div class="grid-gap">
<figure>
<a href="https://via.placeholder.com/397x625">
<img src="https://via.placeholder.com/397x625/255a60/FFFFFF" />
</a>
<figcaption>This is a caption!</figcaption>
</figure>
</div>
</div>
<div class="grid-item">
<div class="grid-gap">
<a href="https://via.placeholder.com/678x765">
<img src="https://via.placeholder.com/678x765/4496a1/FFFFFF" />
</a>
</div>
</div>
<div class="grid-item">
<div class="grid-gap">
<a href="https://via.placeholder.com/567x987">
<img src="https://via.placeholder.com/567x987/eaf8ab/FFFFFF" />
</a>
</div>
</div>
<div class="grid-item">
<div class="grid-gap">
<a href="https://via.placeholder.com/968x956">
<img src="https://via.placeholder.com/968x956/ccd47e/FFFFFF" />
</a>
</div>
</div>
<div class="grid-item">
<div class="grid-gap">
<a href="https://via.placeholder.com/987x687">
<img src="https://via.placeholder.com/987x687/255a60/FFFFFF" />
</a>
</div>
</div>
<div class="grid-item">
<div class="grid-gap">
<a href="https://via.placeholder.com/620x345">
<img src="https://via.placeholder.com/620x345/255a60/FFFFFF" />
</a>
</div>
</div>
<div class="grid-item">
<div class="grid-gap">
<a href="https://via.placeholder.com/543x789">
<img src="https://via.placeholder.com/543x789/4496a1/FFFFFF" />
</a>
</div>
</div>
<div class="grid-item">
<div class="grid-gap">
<a href="https://via.placeholder.com/376x274">
<img src="https://via.placeholder.com/376x274/eaf8ab/FFFFFF" />
</a>
</div>
</div>
<div class="grid-item">
<div class="grid-gap">
<a href="https://via.placeholder.com/468x623">
<img src="https://via.placeholder.com/468x623/9fb828/FFFFFF" />
</a>
</div>
</div>
</div>
simple problem, sometime i have more content in card (make it bigger), and i want the one that is smaller to take automatically the height of the bigger one.
You can see explicitly what i mean on the picture attached.
I'm using quasar (vuejs framework) and stylus
Here is my code for the css of the box :
<style lang="stylus" scoped>
.q-card {
margin: 10px;
width : auto;
img {
height : 150px;
}
}
</style>
UPDATE
And the html concerned :
<ais-results :stack="true" class="row">
<template slot-scope="{ result }">
<div class="col-md-3 col-xs-6">
<q-card>
<q-card-media>
<img :src="result.picture">
</q-card-media>
<q-card-title>
{{result.name_event}}
<q-rating slot="subtitle" :max="5" />
<div slot="right" class="row items-center">
<q-icon name="place" /> 250 ft
</div>
</q-card-title>
<q-card-main>
<p v-if="result.place.location" style="color:#48C8B8">
<q-icon name="place" />{{result.place.name}}, {{result.place.location.city}}
</p>
<p class="text-faded">{{result.start_time}}</p>
</q-card-main>
<q-card-separator />
<q-card-actions>
<q-btn flat round dense icon="event" />
<q-btn flat color="primary" label="Reserve" />
</q-card-actions>
</q-card>
</div>
</template>
</ais-results>
Thanks in advance to the community !
Just use a simple CSS grid:
.grid-container {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-row-gap: 10px;
grid-column-gap: 10px;
}
.q-card {
background-color: #f8f8f8;
box-shadow: 0 0 3px #666;
text-align: center;
}
.q-card img {
max-width: 100%;
}
<div class="grid-container">
<div class="q-card">1 <br />1.1<br />1.1.1</div>
<div class="q-card">2</div>
<div class="q-card">3
<img src="https://lorempixel.com/420/320/abstract/1/Sample" alt="" />
3.1
</div>
<div class="q-card">4</div>
</div>
All grid items will automatically have equal height on a per-row basis, which seems to be exactly what you are looking for.
If you need fixed-width columns, there you go:
grid-template-columns: repeat(2, 500px);
Note: I would be displaying this page on my SharePoint 2010 site.
I am trying to use CSS table to display and following is my HTML code for it:
<div id="cr">
<ul class="contact-img">
<li><img src="Landing page/Contacts/CassWade.png"></li>
<li>Cass Wade<br/>Project Manager</li>
<li><img src="Landing page/Contacts/Meredith.png"></li>
<li>Meredith<br/>HR Head</li>
<li><img src="Landing page/Contacts/Simon.png"></li>
<li>Simon<br/>CEO</li>
<li><img src="Landing page/Contacts/Roger.png"></li>
<li>Roger<br/>Director</li>
<li><img src="Landing page/Contacts/Sharyl.png"></li>
<li>Sharyl<br/>Employee</li>
</ul>
<hr/>
</div>
Here is my CSS for the above page:
.contact-img{
position: relative;
list-style:none;
display:table;
border:none;
padding:none;
margin:none;
}
.contact-img li
{
display:table-cell;
padding:10px 10px 10px 10px;
vertical-align:middle;
margin-left: 25px;
}
I was trying to display these images and its corresponding name in tabular format. The problem with this table is that width of the cell is getting resized as per the content of the cell. However, i want to fix the table cell width (no restrictions on height). Also I want to restrict the number of columns to 4. Any more entries should go to next row.
Any help on how to achieve would be highly appreciated. Thanks in advance.
My solution uses flexbox CSS3 properties to allow the boxes to be aligned and to wrap if the window gets to small. If you don't want this additional responsive behavior, you can change the max-width for width which in any case limits the number element to 4 per line.
I had to add boxing (div) inside to fix the cell size.
HTML:
<ul class="container">
<li>
<div class="inside-container">
<div><img src="http://dummyimage.com/100x100/000/fff.png&text=1"></div>
<div class="description"><div>Cass Wade<br/>Project Manager</div></div>
</div>
</li>
<li>
<div class="inside-container">
<div><img src="http://dummyimage.com/100x100/000/fff.png&text=2"></div>
<div class="description"><div>Meredith<br/>HR Head</div></div>
</div>
</li>
<li>
<div class="inside-container">
<div><img src="http://dummyimage.com/100x100/000/fff.png&text=3"></div>
<div class="description"><div>Simon<br/>CEO</div></div>
</div>
</li>
<li>
<div class="inside-container">
<div><img src="http://dummyimage.com/100x100/000/fff.png&text=4"></div>
<div class="description"><div>Roger<br/>Director</div></div>
</div>
</li>
<li>
<div class="inside-container">
<div><img src="http://dummyimage.com/100x100/000/fff.png&text=5"></div>
<div class="description"><div>Sharyl<br/>Employee</div></div>
</div>
</li>
</ul>
CSS:
.container {
list-style: none;
-webkit-padding-start: 0px; /* fixing Chrome auto style */
display: flex;
flex-wrap: wrap;
max-width: 800px; /* max 4 items of 200px width per line */
}
/* the content as a bloc */
.inside-container {
width: 200px;
height: 100px;
display: flex; /* makes the description to stay next to the image */
}
.inside-container div {
width: 100px;
height: 100px;
}
.inside-container div.description {
text-align: center;
}
.inside-container div.description div {
display:table-cell;
vertical-align: middle;
}
Hope it helps!
edit:
To center your text horizontally you need the container to have text-align: center;.
To center horizontally, you need to put your text in a <div> and add these properties display: table-cell; vertical-align: middle;. It's not as beautiful as I would like, but it works well!
I have a varying number of inline-block divs that I want to collectively take up 100% of their parent. Can this be done without JavaScript? The only way I can think of is with a table but it's of course bad practice to use a table solely for layout purposes.
|----------------------|
|{ div 1 }{ div 2 }|
or
|{div 1}{div 2}{div 3}|
|----------------------|
I have also tried { display:block; float:left; } but it doesn't seem to make a difference.
You can use display:table-cell on your inner divs to do this. For the browser to make the inner divs behave like table cells, it also needs two layers of containing elements: one to acts as the table, and another to act as the table-row.
For a structure like this:
<div class="outer">
<div class="middle">
<div class="inner">Item 1</div>
<div class="inner">Item 2</div>
<div class="inner">Item 3</div>
<div class="inner">Item 4</div>
</div>
</div>
Use this CSS:
div.outer {display:table;}
div.middle {display:table-row;}
div.inner {display:table-cell;}
A nice structure to use is a UL wrapped in a DIV: the DIV acts as a table, the UL as a row, and the LI's as table-cells.
This technique is not well supported in older browsers - for anything older than IE8, you're out of luck entirely.
Let me know if you need more sample code than that!
You can utilize css3 benefits here. I was also facing this issue now i have fixed that using below example code
.parent-container {
padding: 0;
margin: 0;
list-style: none;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row wrap;
justify-content: space-around;
-webkit-justify-content: space-around;
flex-wrap: nowrap;
-webkit-flex-wrap: nowrap;
}
.child-item {
margin: 5px;
text-align: center;
padding: 10px;
background-color: red;
color: #fff;
}
<ul class="parent-container">
<li class="child-item">1</li>
<li class="child-item">2</li>
<li class="child-item">3</li>
<li class="child-item">4</li>
<li class="child-item">5</li>
<li class="child-item">6</li>
<li class="child-item">7</li>
</ul>
Thanks & Regards,
Lingeshram
The accepted answer missed an important CSS property which is necessary to work:
table-layout: fixed;
This is the correct answer:
HTML:
<div class="outer">
<div class="middle">
<div class="inner">Item 1</div>
<div class="inner">Item 2</div>
<div class="inner">Item 3</div>
<div class="inner">Item 4</div>
</div>
</div>
</div>
CSS:
div.outer {display:table; table-layout: fixed;}
div.middle {display:table-row;}
div.inner {display:table-cell;}
I'd like to expound on #lingeshram's answer. Flexboxes have come so far that I think it's really the way to do it now. If you have to support old browsers, be sure to check caniuse first.
.container {
display: flex; /* or inline-flex */
}
.col {
flex-grow: 1;
border: 1px solid #000;
}
.col2x {
flex-grow: 2;
border: 1px solid #000;
}
Evenly split three children
<div class='container'>
<span class='col'>Inner 1</span>
<span class='col'>Inner 2</span>
<span class='col'>Inner 3</span>
</div>
<br>
Evenly split two children
<div class='container'>
<span class='col'>Inner 1</span>
<span class='col'>Inner 2</span>
</div>
<br>
Split three children, but the middle is twice the size of the others
<div class='container'>
<span class='col'>Inner 1</span>
<span class='col2x'>Inner 2</span>
<span class='col'>Inner 3</span>
</div>
Here is a pretty good guide to the different ways you can use flexbox.