
Vertical spacing between columns using Sass as an example bootstrap mesh
Almost any site can not do without blocks of streaming elements, such as: a list of news, products, gallery photos. Such elements are mainly displayed by the template engine in a loop; they occupy an equal number of columns and an unexpected number of rows. If such elements move to the second line, then between them you need to provide vertical indentation so that they do not shrink. Even if the designer brought out only one row on the layout for beauty, it is imperative to provide for an increase in the number of such elements on the layout

. But let's all the same analyze in more detail how to solve such a problem, since pitfalls are present.
We represent that our markup is as follows:
But the problem here is that the parent block itself will recede from the lower ones by 20px, it will not be isolated from the external environment, it will affect the geometry of neighboring blocks. It will be difficult to transfer it to other places on the site or to other projects. In a word, the gallery block will not be independent.
As a result, we need to get something similar to the indentation of the table, where they are applied only inside the table and do not go outside.
We make a vertical indent for each element and a negative vertical indent for the parent of the same magnitude.
Everything seems to be fine, but if a block contains an interactive element, such as a link, in the area that the block overlaps, the block will block it. Here are the links that guidance will not work on the screen.

You can get out of this situation. You need to wrap the gallery block in another block, which is set to overflow: hidden and it will crop all the overflow.
But here another problem arises. All overflow is cut off, and this limits many design decisions. For example, the shadow of a block when hovering over a photo, labels that can climb out for an element, for example, a “Bestseller" label for an item. Also, when hovering over an element, a drop-down block with detailed information and so on may appear.
Ideally, you need to specify the top indent for all elements except the first row. This can be done using the nth-child pseudo-class.
But if you specify it statically, the solution will not be flexible and you will need to change the rules with changing the number of columns, and this is not just not convenient, but completely unsuitable considering the column changes in media queries.
But when using preprocessors, this solution can be made flexible, which is exactly what I want to demonstrate to you. As a basis, I took the Bootstrap grid, that is, each photo gallery we have is placed in the grid column. As a preprocessor, I used Sass. But this approach can be safely applied to other grids and preprocessors.
Let me remind you that the columns in the bootstrap grid are written in the following classes:
col-xs- *
col-sm- *
col-md- *
col-lg- *
Let's imagine that our gallery is enclosed in 3 columns on average screen sizes, that is, col-md-4. For versatility, we will indent for the columns of the grid for which the row-vertical-indent modifier is assigned.
Now we write Sass styles
As a result, all elements starting from the 4th will be indented from above. The first 3 will be indented.
Let's expand the possibilities and provide any number of columns on medium-sized screens
The $ grid-columns variable is an internal bootstrap variable that is assigned the number of grid columns. The default is 12.
We run through the cycle for all possible number of columns and assign indents for those elements that do not fit in 12 columns, respectively, go to the second row.
But we also do not know how many columns will be for other break points, so we need to sort through all the options for media queries.
We create an object (I can’t get used to the terminology “map”) of media queries.
The key is the breakpoint designation in the class name, that is, col-xs .., col-sm .., col-md ...
The value is the media rotation itself for each break point.
Next, we go over this object and for each iteration we apply the previous design, but for a specific media rotation.
Do not forget to select the value of the object key instead of md in the name of the selectors. # {$ key}
Next, I propose to wrap it all up in an admixture and set the indent value dynamically through an argument.
As a result, we get such an impurity that can expand the capabilities of the bootstrap grid.
Now for the desired class, just call the impurity passing indent
1 - Works correctly only for the same number of columns in a row.
That is, for the dynamic flow of columns that are displayed in a cycle (product catalog, news, gallery, etc.).
For a static number of columns, for example, for marking up the page itself, such a solution may not work correctly, and in principle it is not necessary in order not to clutter the compiled CSS code. In this case, it is even more convenient for individual classes to add indentation where necessary.
2 - It is necessary to specify all break points for the column.
My solution does not provide a mobile first approach and styles will not be applied on the screen for which the number of columns is not indicated.
In bootstrap, this entry means that there will be 3 columns for all sizes starting with sm.
But when using vertical indents, the number of columns must be specified for all sizes, that is, the record will look like this
I tried to provide a mobile first approach, but ran into terrible hemorrhages related to redefinition of styles, which as a result scored. If anyone succeeds, let me know, I will be very grateful.
3 - Tin in compiled CSS.
If someone has to edit the compiled css file, then there will be a lot of garbage. I personally do not care, but you never know.

. But let's all the same analyze in more detail how to solve such a problem, since pitfalls are present.
Indent for each item
We represent that our markup is as follows:
But the problem here is that the parent block itself will recede from the lower ones by 20px, it will not be isolated from the external environment, it will affect the geometry of neighboring blocks. It will be difficult to transfer it to other places on the site or to other projects. In a word, the gallery block will not be independent.
As a result, we need to get something similar to the indentation of the table, where they are applied only inside the table and do not go outside.
Negative indent for block
We make a vertical indent for each element and a negative vertical indent for the parent of the same magnitude.
.gallery{
margin-top: -20px
}
.gallery__image{
margin-top: 20px
}
Everything seems to be fine, but if a block contains an interactive element, such as a link, in the area that the block overlaps, the block will block it. Here are the links that guidance will not work on the screen.

You can get out of this situation. You need to wrap the gallery block in another block, which is set to overflow: hidden and it will crop all the overflow.
.gallery{
overflow: hidden;
}
.gallery__inner{
margin-top: -20px
}
.gallery__image{
margin-top: 20px
}
But here another problem arises. All overflow is cut off, and this limits many design decisions. For example, the shadow of a block when hovering over a photo, labels that can climb out for an element, for example, a “Bestseller" label for an item. Also, when hovering over an element, a drop-down block with detailed information and so on may appear.
Indent for each item except the first n
Ideally, you need to specify the top indent for all elements except the first row. This can be done using the nth-child pseudo-class.
But if you specify it statically, the solution will not be flexible and you will need to change the rules with changing the number of columns, and this is not just not convenient, but completely unsuitable considering the column changes in media queries.
But when using preprocessors, this solution can be made flexible, which is exactly what I want to demonstrate to you. As a basis, I took the Bootstrap grid, that is, each photo gallery we have is placed in the grid column. As a preprocessor, I used Sass. But this approach can be safely applied to other grids and preprocessors.
Let me remind you that the columns in the bootstrap grid are written in the following classes:
col-xs- *
col-sm- *
col-md- *
col-lg- *
Let's imagine that our gallery is enclosed in 3 columns on average screen sizes, that is, col-md-4. For versatility, we will indent for the columns of the grid for which the row-vertical-indent modifier is assigned.
Now we write Sass styles
.row-vertical-indent{
& > [class~="col-md-4"]:nth-child(n+4){
padding-top: 20px;
}
}
As a result, all elements starting from the 4th will be indented from above. The first 3 will be indented.
Let's expand the possibilities and provide any number of columns on medium-sized screens
.row-vertical-indent{
@for $i from 1 through $grid-columns{
$nth-element: floor(($grid-columns / $i) + 1);
& > [class~="col-md-#{$i}"]:nth-child(n+#{$nth-element}) {
padding-top: 20px;
}
}
}
The $ grid-columns variable is an internal bootstrap variable that is assigned the number of grid columns. The default is 12.
We run through the cycle for all possible number of columns and assign indents for those elements that do not fit in 12 columns, respectively, go to the second row.
But we also do not know how many columns will be for other break points, so we need to sort through all the options for media queries.
We create an object (I can’t get used to the terminology “map”) of media queries.
The key is the breakpoint designation in the class name, that is, col-xs .., col-sm .., col-md ...
The value is the media rotation itself for each break point.
$break-points: (
'xs': '(max-width: #{$screen-xs-max})',
'sm': '(min-width: #{$screen-sm-min}) and (max-width: #{$screen-sm-max})',
'md': '(min-width: #{$screen-md-min}) and (max-width: #{$screen-md-max})',
'lg': '(min-width: #{$screen-lg-min})'
);
Next, we go over this object and for each iteration we apply the previous design, but for a specific media rotation.
@each $key, $val in $break-points{
@media #{$val}{
@for $i from 1 through $grid-columns{
$nth-element: floor(($grid-columns / $i) + 1);
& > [class~="col-#{$key}-#{$i}"]:nth-child(n+#{$nth-element}){
padding-top: $gutter;
}
}
}
}
Do not forget to select the value of the object key instead of md in the name of the selectors. # {$ key}
Next, I propose to wrap it all up in an admixture and set the indent value dynamically through an argument.
As a result, we get such an impurity that can expand the capabilities of the bootstrap grid.
@mixin grid-vetical-gutter($gutter){
$break-points: (
'xs': '(max-width: #{$screen-xs-max}) ',
'sm': '(min-width: #{$screen-sm-min}) and (max-width: #{$screen-sm-max})',
'md': '(min-width: #{$screen-md-min}) and (max-width: #{$screen-md-max})',
'lg': '(min-width: #{$screen-lg-min})'
);
@each $key, $val in $break-points{
@media #{$val}{
@for $i from 1 through $grid-columns{
$nth-element: floor(($grid-columns / $i) + 1);
& > [class~="col-#{$key}-#{$i}"]:nth-child(n+#{$nth-element}){
padding-top: $gutter;
}
}
}
}
}
Now for the desired class, just call the impurity passing indent
.row-vertical-indent{
@include grid-vetical-gutter(20px)
}
Limitations and disadvantages of this approach:
1 - Works correctly only for the same number of columns in a row.
That is, for the dynamic flow of columns that are displayed in a cycle (product catalog, news, gallery, etc.).
For a static number of columns, for example, for marking up the page itself, such a solution may not work correctly, and in principle it is not necessary in order not to clutter the compiled CSS code. In this case, it is even more convenient for individual classes to add indentation where necessary.
2 - It is necessary to specify all break points for the column.
My solution does not provide a mobile first approach and styles will not be applied on the screen for which the number of columns is not indicated.
In bootstrap, this entry means that there will be 3 columns for all sizes starting with sm.
But when using vertical indents, the number of columns must be specified for all sizes, that is, the record will look like this
I tried to provide a mobile first approach, but ran into terrible hemorrhages related to redefinition of styles, which as a result scored. If anyone succeeds, let me know, I will be very grateful.
3 - Tin in compiled CSS.
If someone has to edit the compiled css file, then there will be a lot of garbage. I personally do not care, but you never know.