Mobile First Breakpoints for nth child - css

I have this code that works, it is a group of client icons that starts off with a 2 column list on mobile, then gradually moves to a 3 column list and then onto a 4 column list and so on.
I am using the nth child pseudo element to remove the margin on certain numbers depending on the breakpoint i.e :nth-child(2n) on the column breakpoint.
But check my code out I feel it is messy, Does anyone know of a better way to write this?
.list-horiz-images li {
float: left;
margin-right: 7px;
margin-bottom: 7px;
width: 49%;
&:nth-child(2n) {
margin-right: 0px;
}
#include mobilefirst(em(670)) {
width: 32.57%;
&:nth-child(2n) {
margin-right: 7px;
}
&:nth-child(3n) {
margin-right: 0px;
}
}
#include mobilefirst(em(1024)) {
width: 24.44%;
&:nth-child(2n) {
margin-right: 7px;
}
&:nth-child(3n) {
margin-right: 7px;
}
&:nth-child(4n) {
margin-right: 0px;
}
}
#include mobilefirst(em($bp-large)) {
width: 13.666666666%;
&:nth-child(2n) {
margin-right: 7px;
}
&:nth-child(3n) {
margin-right: 7px;
}
&:nth-child(4n) {
margin-right: 7px;
}
}
}

Related

Selector is exceeding selector-max-specificity

Here's the CSS that I have:
.tab {
border: 0;
flex: 1 1 0;
min-height: 48px;
opacity: 1;
text-align: center;
z-index: 0;
}
.tab:not([data-selected]) {
border-radius: 0;
}
.tab[data-selected] {
background-color: $white;
border: 1px solid #eee;
z-index: 2;
}
.tab[data-selected]:first-of-type {
margin-right: -8px;
}
.tab[data-selected]:last-of-type {
margin-left: -8px;
}
.tab[data-selected]:not(:first-of-type):not(:last-of-type) {
margin-left: -8px;
margin-right: -8px;
}
.tab:first-of-type {
border-bottom-left-radius: 12px;
border-top-left-radius: 12px;
}
.tab:last-of-type {
border-bottom-right-radius: 12px;
border-top-right-radius: 12px;
}
Having problem with this bit here:
.tab[data-selected]:not(:first-of-type):not(:last-of-type) {
margin-left: -8px;
margin-right: -8px;
}
I'm trying to select the middle child when it is selected. My stylelint is complaining like so:
Expected "`.tab[data-selected]:not(:first-of-type):not(:last-of-type)`" to have a specificity no more than "0,3,2"
How do I approach this in a better way?
The total specificity of your selector
.tab[data-selected]:not(:first-of-type):not(:last-of-type)
is (0,4,0), which is 1 over the limit of (0,3,2).
You can increase selector-max-specificity to accommodate this selector since the difference is so small.
Or if you'd rather not do that, you can refactor your &[data-selected] CSS rules like this. Apply both negative margins by default, then selectively remove the negative margins from &:first-of-type and &:last-of-type, thereby eliminating the need for the double negation:
&[data-selected] {
background-color: $white;
margin-left: -8px;
margin-right: -8px;
border: 1px solid #eee;
z-index: 2;
&:first-of-type {
margin-left: 0; /* Preserve negative margin-right */
}
&:last-of-type {
margin-right: 0; /* Preserve negative margin-left */
}
}
Note that the margin directions are swapped in the two nested rules since we're trying to preserve the now-existing negative margins instead of adding them where they weren't there before.

How to overwrite Referencing Parent Selector using Mixin in SCSS

I had a common used component and its scss is like this:
.component {
margin-right: 12px;
&.specified-use-case {
margin-right: 30px;
&:nth-child(odd) {
margin-right: 70px
}
}
}
Now I want everything has same style in mobile view
.component {
margin-right: 12px;
// some predefined mixin
#include viewport(mobile) {
margin-right: 0px;
margin-bottom: 14px;
}
&.specified-use-case {
margin-right: 30px;
&:nth-child(odd) {
margin-right: 70px
}
}
}
But this can't change style for "specified-use-case" in mobile view. In order to do it I have to
.component {
margin-right: 12px;
// some predefined mixin
#include viewport(mobile) {
margin-right: 0px;
margin-bottom: 14px;
}
&.specified-use-case {
margin-right: 30px;
#include viewport(mobile) {
margin-right: 0px;
margin-bottom: 14px;
}
&:nth-child(odd) {
margin-right: 70px
#include viewport(mobile) {
margin-right: 0px;
margin-bottom: 14px;
}
}
}
}
Which just doesn't seem right to me. Is there a better way to define mobile view css just for once?
According to CSS' specificity rules (try this calculator) you unfortunately need to repeat yourself. What your SCSS interpreter does is just compiling what you've written to standard CSS, which will look something akin to:
.component {
margin-right:12px
}
#media (max-width:768px) {
.component {
margin-right:0px;
margin-bottom:14px
}
}
.component.specified-use-case {
margin-right:30px
}
#media (max-width:768px) {
.component.specified-use-case {
margin-right:0px;
margin-bottom:14px
}
}
.component.specified-use-case:nth-child(odd) {
margin-right:70px
}
#media (max-width:768px) {
.component.specified-use-case:nth-child(odd) {
margin-right:0px;
margin-bottom:14px
}
}
As you can see, you're overriding each class with a #media ruleset just after it has been declared. And since I'm a big proponent to never use !important (because you'll open a pandoras box), the only way you can shorten your SCSS is doing:
.component {
margin-right: 12px;
// some predefined mixin
#include viewport(mobile) {
margin-right: 0px;
margin-bottom: 14px; // only need to define margin-bottom once, here.
}
&.specified-use-case {
margin-right: 30px;
#include viewport(mobile) {
margin-right: 0px;
//margin-bottom: 14px;, remove this
}
&:nth-child(odd) {
margin-right: 70px
#include viewport(mobile) {
margin-right: 0px;
//margin-bottom: 14px;, remove this
}
}
}
}
Hope this helps!
You can put the rules inside of the media query:
#include viewport(mobile) {
margin-right: 0px;
margin-bottom: 14px;
&.specified-use-case {
margin-right: 0px;
margin-bottom: 14px;
}
}
seems like sass is wrong because you specify margins above a breakpoint, try this:
.component {
margin-right: 12px;
&.specified-use-case {
margin-right: 30px;
&:nth-child(odd) {
margin-right: 70px
}
}
// some predefined mixin
#include viewport(mobile) {
margin-right: 0px;
margin-bottom: 14px;
}
}

Twitter Bootstrap: margin-bottom built in css class

Is there built in margin bottom class to use?
I tried with bottom5 like
<div class="col-lg-2 bottom5"></div>
but this doesn't work.
Boostrap 4 has a spacing feature that solves that problem https://getbootstrap.com/docs/4.0/utilities/spacing/
But, in you are sticked to older bootstrap version or can't use it a all and in case you need a complete list of margin and padding classes, here it is
/* MARGINS & PADDINGS */
.p-xxs {
padding: 5px !important;
}
.p-xs {
padding: 10px !important;
}
.p-sm {
padding: 15px !important;
}
.p-m {
padding: 20px !important;
}
.p-md {
padding: 25px !important;
}
.p-lg {
padding: 30px !important;
}
.p-xl {
padding: 40px !important;
}
.m-xxs {
margin: 2px 4px;
}
.m-xs {
margin: 5px;
}
.m-sm {
margin: 10px;
}
.m {
margin: 15px;
}
.m-md {
margin: 20px;
}
.m-lg {
margin: 30px;
}
.m-xl {
margin: 50px;
}
.m-n {
margin: 0 !important;
}
.m-l-none {
margin-left: 0;
}
.m-l-xs {
margin-left: 5px;
}
.m-l-sm {
margin-left: 10px;
}
.m-l {
margin-left: 15px;
}
.m-l-md {
margin-left: 20px;
}
.m-l-lg {
margin-left: 30px;
}
.m-l-xl {
margin-left: 40px;
}
.m-l-n-xxs {
margin-left: -1px;
}
.m-l-n-xs {
margin-left: -5px;
}
.m-l-n-sm {
margin-left: -10px;
}
.m-l-n {
margin-left: -15px;
}
.m-l-n-md {
margin-left: -20px;
}
.m-l-n-lg {
margin-left: -30px;
}
.m-l-n-xl {
margin-left: -40px;
}
.m-t-none {
margin-top: 0;
}
.m-t-xxs {
margin-top: 1px;
}
.m-t-xs {
margin-top: 5px;
}
.m-t-sm {
margin-top: 10px;
}
.m-t {
margin-top: 15px;
}
.m-t-md {
margin-top: 20px;
}
.m-t-lg {
margin-top: 30px;
}
.m-t-xl {
margin-top: 40px;
}
.m-t-xxl {
margin-top: 50px;
}
.m-t-xxxl {
margin-top: 60px;
}
.m-t-n-xxs {
margin-top: -1px;
}
.m-t-n-xs {
margin-top: -5px;
}
.m-t-n-sm {
margin-top: -10px;
}
.m-t-n {
margin-top: -15px;
}
.m-t-n-md {
margin-top: -20px;
}
.m-t-n-lg {
margin-top: -30px;
}
.m-t-n-xl {
margin-top: -40px;
}
.m-r-none {
margin-right: 0;
}
.m-r-xxs {
margin-right: 1px;
}
.m-r-xs {
margin-right: 5px;
}
.m-r-sm {
margin-right: 10px;
}
.m-r {
margin-right: 15px;
}
.m-r-md {
margin-right: 20px;
}
.m-r-lg {
margin-right: 30px;
}
.m-r-xl {
margin-right: 40px;
}
.m-r-n-xxs {
margin-right: -1px;
}
.m-r-n-xs {
margin-right: -5px;
}
.m-r-n-sm {
margin-right: -10px;
}
.m-r-n {
margin-right: -15px;
}
.m-r-n-md {
margin-right: -20px;
}
.m-r-n-lg {
margin-right: -30px;
}
.m-r-n-xl {
margin-right: -40px;
}
.m-b-none {
margin-bottom: 0;
}
.m-b-xxs {
margin-bottom: 1px;
}
.m-b-xs {
margin-bottom: 5px;
}
.m-b-sm {
margin-bottom: 10px;
}
.m-b {
margin-bottom: 15px;
}
.m-b-md {
margin-bottom: 20px;
}
.m-b-lg {
margin-bottom: 30px;
}
.m-b-xl {
margin-bottom: 40px;
}
.m-b-n-xxs {
margin-bottom: -1px;
}
.m-b-n-xs {
margin-bottom: -5px;
}
.m-b-n-sm {
margin-bottom: -10px;
}
.m-b-n {
margin-bottom: -15px;
}
.m-b-n-md {
margin-bottom: -20px;
}
.m-b-n-lg {
margin-bottom: -30px;
}
.m-b-n-xl {
margin-bottom: -40px;
}
.space-15 {
margin: 15px 0;
}
.space-20 {
margin: 20px 0;
}
.space-25 {
margin: 25px 0;
}
.space-30 {
margin: 30px 0;
}
It's taken from Homer Responsive Admin Theme by WebAppLayers. I guess author don't mind sharing that. It probably will save 20min of time of some Web Developer out there.
Now available in bootstrap 4
Example-
<div class="mb-5 p-5">
margin-bottom and padding with size 5
</div>
You can use-
m for margin
p for padding
And for sides:
t - top
b - bottom
l - left
r - right
x - both left & right
y - both top & bottom
blank -all sides
For size- 0,1,2,3,4,5
There is no bootstrap class for margins like you describe. The reasons would be the need for classes for margins 0 to 10s or 100s, as well as the need for multiple units, such as px, em, %, etc.
You can make your own classes fairly easy. Even easier with sublime text-editor and multi-select.
That being said, you don't want to abstract every style rule into the html. Original CSS is useful for something particular to your element, such as margins. Using bootstrap classes for every style would lead to difficult to read HTML.
This Question is tagged Bootstrap 3, but when you update to Bootstrap 4, there is a built in utility for this.
Try adding the class, named
margin-bottom-5
The classes are named using the format: {property}-{sides}-{size}
from: here
UPDATE : Bootstrap 4 Classes
Bootstrap 4 classes to add margin and padding
Bootstrap 4 has a wide range of responsive margin and padding utility classes. They work for all breakpoints: xs (<=576px), sm (>=576px), md (>=768px), lg (>=992px) or xl (>=1200px)):
The classes are used in the format: {property}{sides}-{size}
for xs and {property}{sides}-{breakpoint}-{size} for sm, md, lg, and xl.
Where property is one of:
m - sets margin
p - sets padding
Where sides is one of:
t - sets margin-top or padding-top
b - sets margin-bottom or padding-bottom
l - sets margin-left or padding-left
r - sets margin-right or padding-right
x - sets both padding-left and padding-right or margin-left and margin-right(X-axis)
y - sets both padding-top and padding-bottom or margin-top and margin-bottom(Y-axis)
blank - sets a margin or padding on all 4 sides of the element
Where size is one of:
0 - sets margin or padding to 0
1 - sets margin or padding to .25rem (4px if font-size is 16px)
2 - sets margin or padding to .5rem (8px if font-size is 16px)
3 - sets margin or padding to 1rem (16px if font-size is 16px)
4 - sets margin or padding to 1.5rem (24px if font-size is 16px)
5 - sets margin or padding to 3rem (48px if font-size is 16px)
auto - sets margin to auto
Reference Links : https://getbootstrap.com/docs/4.0/utilities/spacing/
HOW TO USE
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<div class="pt-4 bg-warning">I only have a top padding (1.5rem = 24px)</div>
<div class="p-5 bg-success">I have a padding on all sides (3rem = 48px)</div>
<div class="m-5 pb-5 bg-info">I have a margin on all sides (3rem = 48px) and a bottom padding (3rem = 48px)</div>
If you want to add margin bottom you can add from mb-0 to mb-5.
See :https://getbootstrap.com/docs/4.4/utilities/spacing/

How to effectively write -sm, -md, -lg padding classes in LESS

I'm trying to create standard classes that can be used to add different amounts of padding. This would be added to the individual elements within the DOM to control padding/margins. I'd like to eventually leverage it for different sizes and for margins as well. This is how I've begun to write it in LESS, but is there a shorter way to write this?
#padding-sm: 5px;
#padding-md: 10px;
#padding-lg: 20px;
.padding-sm {
padding: #padding-sm;
}
.padding-sm-h {
padding-right: #padding-sm;
padding-left: #padding-sm;
}
.padding-sm-v {
padding-top: #padding-sm;
padding-bottom: #padding-sm;
}
.padding-sm-top {
padding-top: #padding-sm;
}
.padding-sm-right {
padding-right: #padding-sm;
}
.padding-sm-bottom {
padding-bototm: #padding-sm;
}
.padding-none {
padding: 0;
}
For LESS 1.7+
This uses the .for looping code that can be found here, which is normally recommended to be saved in a separate less file and imported, like so:
#import "for";
Assuming that code is in place, whether by import or hard copied in, then you can build the following mixin:
.setPadding(#size) {
#s: ~"-#{size}";
#getSize: ~"padding#{s}";
#getValue: ##getSize;
#directions: top right bottom left;
#pairs: h right left, v top bottom;
.appendPadding() {.padding& { #props();}}
#{s} {
//set all directions
& {
#props: {padding: #getValue;};
.appendPadding();
}
//set paired directions
& {
.for(#pairs); .-each(#pair) {
#name: extract(#pair, 1);
#one: extract(#pair, 2);
#two: extract(#pair, 3);
&-#{name} {
#props: {
padding-#{one}: #getValue;
padding-#{two}: #getValue;
};
.appendPadding();
}
}
}
//set four base directions
& {
.for(#directions); .-each(#dir) {
&-#{dir} {
#props: {padding-#{dir}: #getValue;};
.appendPadding();
}
}
}
}
}
Now the above looks vastly more complicated than your original code, but it gets its power by its ability to easily reproduce for all your sizing levels. So with the above code, then the following minimal amount of code defines your three groups into CSS as you are desiring:
#padding-sm: 5px;
#padding-md: 10px;
#padding-lg: 20px;
.setPadding(sm);
.setPadding(md);
.setPadding(lg);
.padding-none {
padding: 0;
}
CSS Output
.padding-sm {
padding: 5px;
}
.padding-sm-h {
padding-right: 5px;
padding-left: 5px;
}
.padding-sm-v {
padding-top: 5px;
padding-bottom: 5px;
}
.padding-sm-top {
padding-top: 5px;
}
.padding-sm-right {
padding-right: 5px;
}
.padding-sm-bottom {
padding-bottom: 5px;
}
.padding-sm-left {
padding-left: 5px;
}
.padding-md {
padding: 10px;
}
.padding-md-h {
padding-right: 10px;
padding-left: 10px;
}
.padding-md-v {
padding-top: 10px;
padding-bottom: 10px;
}
.padding-md-top {
padding-top: 10px;
}
.padding-md-right {
padding-right: 10px;
}
.padding-md-bottom {
padding-bottom: 10px;
}
.padding-md-left {
padding-left: 10px;
}
.padding-lg {
padding: 20px;
}
.padding-lg-h {
padding-right: 20px;
padding-left: 20px;
}
.padding-lg-v {
padding-top: 20px;
padding-bottom: 20px;
}
.padding-lg-top {
padding-top: 20px;
}
.padding-lg-right {
padding-right: 20px;
}
.padding-lg-bottom {
padding-bottom: 20px;
}
.padding-lg-left {
padding-left: 20px;
}
.padding-none {
padding: 0;
}

Creating multiple classes with LESS function

I want to accomplish this css (and more not posted for brevity) with LESS so I can have more control and auto creation of classes.
Not sure how much LESS can help me with it.
.m-xs {
margin-top: 5px;
margin-right: 5px;
margin-bottom: 5px;
margin-left: 5px;
}
.m-t-xs{
margin-top: 5px;
}
.m-r-xs{
margin-right: 5px;
}
.m-b-xs{
margin-bottom: 5px;
}
.m-l-xs{
margin-left: 5px;
}
.m-h-xs{
margin-right: 5px;
margin-left: 5px;
}
.m-v-xs{
margin-top: 5px;
margin-bottom: 5px;
}
I want this to be repeated for several sizes (xs, s, m, l, xl, etc) and also other properties like padding.
how can I use less to do this kind of 'autocreate' thing ? is even possible without writing all the classes?
I never used LESS but I see heavy use of it on bootstrap and I think this can be achieved.
I tested few things but looks like it's an advanced scenario because none of the tutorials have it covered.
thanks!
To generate the classes that you've mentioned there you could try parameterised mixins:
.classes (#size) {
.m-#{size} {
margin-top: 5px;
margin-right: 5px;
margin-bottom: 5px;
margin-left: 5px;
}
.m-t-#{size}{
margin-top: 5px;
}
.m-r-#{size} {
margin-right: 5px;
}
.m-b-#{size} {
margin-bottom: 5px;
}
.m-l-#{size} {
margin-left: 5px;
}
.m-h-#{size} {
margin-right: 5px;
margin-left: 5px;
}
.m-v-#{size} {
margin-top: 5px;
margin-bottom: 5px;
}
}
.classes(xs);
.classes(s);
.classes(m);
.classes(l);
.classes(xl);
Further parameterising as necessary.

Resources