arnekolja arnekolja - 2 months ago 7
CSS Question

CSS: How to define spacing between responsive columns

I need to provide an interface for a project where an editor is able to define container elements with some variables: He/she should be able to define how many columns there are, and how they behave on different screen sizes.

For this purpose I took a grid framework (here: PureCSS responsive grids) and let him/her choose which column size a given column has for a given screen size. So it can be defined whether on screen size "large" there should be two or three columns in that row before it breaks to the next row.

I am explaining this not because of the technical part of it, but because I'm running into trouble because of it.

The situation is, that the page layout needs padding between those columns, but not at the outer side of the row.

I am trying to solve this using a bit of customization of CSS rules on top of the framework in use, which works fine - as long as it is a single row that doesn't wrap to the next line. When having a smaller screen width, it wraps like it should, but the paddings don't work that way any more.

Do you have any idea how I could solve this, having in mind that it should consist of rules that apply "automatically", without the need to rely on additional CSS classes?

I have made a fiddle to demonstrate my problem. The editor should not have to define paddings for each screen size, as he already defines column sizes for it. The padding should work "automatically" in that manner.

<style>
/* Using SCSS for convenience */
body {
padding: 1em;
}

.pure-g {
margin-bottom: 1em;

> div {
border: thin solid black;
box-sizing: border-box;
padding: 0 .5em 1em .5em;

&:first-child {
padding-left: 0;
padding-right: .66em;
}

&:last-child {
padding-left: .66em;
padding-right: 0;
}

> div {
box-sizing: border-box;
height: 10em;
background-color: green;
}
}

&[data-cols="3"] {
> div:nth-child(2) {
padding-left: .33em;
padding-right: .33em;
}
}

&[data-cols="4"] {
> div:nth-child(2) {
padding-left: .33em;
}

> div:nth-child(3) {
padding-right: .33em;
}
}
}
</style>

<div class="pure-g" data-cols="3">
<div class="pure-u-1 pure-u-md-1-2 pure-u-lg-1-3"><div></div></div>
<div class="pure-u-1 pure-u-md-1-2 pure-u-lg-1-3"><div></div></div>
<div class="pure-u-1 pure-u-md-1 pure-u-lg-1-3"><div></div></div>
</div>

<div class="pure-g" data-cols="4">
<div class="pure-u-1 pure-u-md-1-2 pure-u-lg-1-4"><div></div></div>
<div class="pure-u-1 pure-u-md-1-2 pure-u-lg-1-4"><div></div></div>
<div class="pure-u-1 pure-u-md-1-2 pure-u-lg-1-4"><div></div></div>
<div class="pure-u-1 pure-u-md-1-2 pure-u-lg-1-4"><div></div></div>
</div>

<div class="pure-g" data-cols="5">
<div class="pure-u-1 pure-u-md-1-2 pure-u-lg-1-5"><div></div></div>
<div class="pure-u-1 pure-u-md-1-2 pure-u-lg-1-5"><div></div></div>
<div class="pure-u-1 pure-u-md-1-2 pure-u-lg-1-5"><div></div></div>
<div class="pure-u-1 pure-u-md-1-2 pure-u-lg-1-5"><div></div></div>
<div class="pure-u-1 pure-u-md-1 pure-u-lg-1-5"><div></div></div>
</div>


A short explanation of what I am doing so far:


  • Body should have padding, so the columns do not touch the page border. One could argue, that this could be handled by the columns, but in my real situation there's more to it: A constrained container width instead of the body.

  • Columns should always have 1em padding between each other, and 1em margin to the bottom.

  • To make the columns of equal inner size, I have to adjust the padding a bit: Because of the fact that there is no outer padding, the first and the last column need to adjust their paddings, same with the ones they're touching. I think you'll see what I mean.

  • (Borders and inner div are just to visualize things)



https://jsfiddle.net/1jv43g02/

Thanks for your help

Arne

Answer

From comments:

Take an example on Twitter Bootstrap. Collumns have the same right and left padding padding: 0 20px; and rows will negate that padding via margin: 0 -20px; causing the row to fill the desired 100% of the container