Bootstrap 4 margin and padding utilities are generated in /scss/utilities/_spacing.scss.
These are generated in an order like
.p-0 { ... }
.pt-0, .py-0 { ... }
.pr-0, .px-0 { ... }
.pb-0, .py-0 { ... }
.pl-0, .px-0 { ... }
.p-1 { ... }
.pt-1, .py-1 { ... }
. . .
because of this order, if you set a padding or margin for all sides of the element, you can only override a side with a utility that has a direction with a greater value. For example:
class="m-3 mt-0" would show the top margin from .m-3 (pen)
class="m-3 mt-5" would show the top margin from .mt-5
This results in a behavior where (without factoring in media queries and breakpoints), the largest value assigned by a spacing utility is the one that sticks.
I feel that this behavior is flawed because it would make more sense for more specific classes to take precedence over more general ones.
For the simple case of class="m-3 mt-0", it's an easy enough solution to just set a margin for each side. class="mx-3, mb-3" as it only adds one more character to produce the desired effect.
For more complicated margins and padding that also utilize media queries, there may not be as easy of a fix.
An easy solution for this would be to just reorder these classes:
.p-0 { ... }
.p-1 { ... }
.p-2 { ... }
.p-3 { ... }
.p-4 { ... }
.p-5 { ... }
.pt-0, .py-0 { ... }
.pt-1, .py-1 { ... }
.pt-2, .py-2 { ... }
. . .
There is an inconsistent behavior right now where some more specific spacing utilities will override the generic margin and padding, but others will not. Reordering the classes by changing the SCSS loop would resolve this behavior. Please consider implementing this solution
What you 're suggestion is a breaking change, so this is probably not something we can do in v4 yet.
What you're trying to do is possible with other utilities, for example .m-3 on every side except on the top would beclass="mx-3 mb-3". This would be a better approach, because you're not overwriting other utility classes.
But you're right about the strange behaviour of class="m-3 mt-0" and class="m-3 mt-5". We'll need to review our @each loop to solve this.
Something we can look into in v5 I guess? (ping rest of @twbs/css-review)
The class="m-3 mt-0" / class="m-3 mt-5" thing is something we can look in to in v4.3, I'll add it to the project.
I wonder if this could be a breaking change for projects that use a lot of spacing classes?
Already fixed for v5 馃槷 (#28445)
Most helpful comment
Already fixed for v5 馃槷 (#28445)