Closed qbixx closed 4 years ago
Following @ilicmarko's comment, here's my
spacing.scss
file…$sizeUnit: rem; $marginKey: 'm'; $paddingKey: 'p'; $separator: '-'; $sizes: ( ('none', 0), ('xxs', 0.125), ('xs', 0.25), ('sm', 0.5), ('md', 1), ('lg', 2), ('xl', 4), ('xxl', 8), ); $positions: ( ('t', 'top'), ('r', 'right'), ('b', 'bottom'), ('l', 'left') ); @function sizeValue($key, $value) { @return if($key == 'none', 0, $value + $sizeUnit); } @each $size in $sizes { $sizeKey: nth($size, 1); $sizeValue: nth($size, 2); .#{$marginKey}#{$separator}#{$sizeKey} { margin: sizeValue($sizeKey, $sizeValue); } .#{$paddingKey}#{$separator}#{$sizeKey} { padding: sizeValue($sizeKey, $sizeValue); } @each $position in $positions { $posKey: nth($position, 1); $posValue: nth($position, 2); .#{$marginKey}#{$separator}#{$posKey}#{$separator}#{$sizeKey} { margin-#{$posValue}: sizeValue($sizeKey, $sizeValue); } .#{$paddingKey}#{$separator}#{$posKey}#{$separator}#{$sizeKey} { padding-#{$posValue}: sizeValue($sizeKey, $sizeValue); } } }
…which generates the following classes…
.m-none { margin: 0; } .p-none { padding: 0; } .m-t-none { margin-top: 0; } .p-t-none { padding-top: 0; } .m-r-none { margin-right: 0; } .p-r-none { padding-right: 0; } .m-b-none { margin-bottom: 0; } .p-b-none { padding-bottom: 0; } .m-l-none { margin-left: 0; } .p-l-none { padding-left: 0; } .m-xxs { margin: 0.125rem; } .p-xxs { padding: 0.125rem; } .m-t-xxs { margin-top: 0.125rem; } .p-t-xxs { padding-top: 0.125rem; } .m-r-xxs { margin-right: 0.125rem; } .p-r-xxs { padding-right: 0.125rem; } .m-b-xxs { margin-bottom: 0.125rem; } .p-b-xxs { padding-bottom: 0.125rem; } .m-l-xxs { margin-left: 0.125rem; } .p-l-xxs { padding-left: 0.125rem; } .m-xs { margin: 0.25rem; } .p-xs { padding: 0.25rem; } .m-t-xs { margin-top: 0.25rem; } .p-t-xs { padding-top: 0.25rem; } .m-r-xs { margin-right: 0.25rem; } .p-r-xs { padding-right: 0.25rem; } .m-b-xs { margin-bottom: 0.25rem; } .p-b-xs { padding-bottom: 0.25rem; } .m-l-xs { margin-left: 0.25rem; } .p-l-xs { padding-left: 0.25rem; } .m-sm { margin: 0.5rem; } .p-sm { padding: 0.5rem; } .m-t-sm { margin-top: 0.5rem; } .p-t-sm { padding-top: 0.5rem; } .m-r-sm { margin-right: 0.5rem; } .p-r-sm { padding-right: 0.5rem; } .m-b-sm { margin-bottom: 0.5rem; } .p-b-sm { padding-bottom: 0.5rem; } .m-l-sm { margin-left: 0.5rem; } .p-l-sm { padding-left: 0.5rem; } .m-md { margin: 1rem; } .p-md { padding: 1rem; } .m-t-md { margin-top: 1rem; } .p-t-md { padding-top: 1rem; } .m-r-md { margin-right: 1rem; } .p-r-md { padding-right: 1rem; } .m-b-md { margin-bottom: 1rem; } .p-b-md { padding-bottom: 1rem; } .m-l-md { margin-left: 1rem; } .p-l-md { padding-left: 1rem; } .m-lg { margin: 2rem; } .p-lg { padding: 2rem; } .m-t-lg { margin-top: 2rem; } .p-t-lg { padding-top: 2rem; } .m-r-lg { margin-right: 2rem; } .p-r-lg { padding-right: 2rem; } .m-b-lg { margin-bottom: 2rem; } .p-b-lg { padding-bottom: 2rem; } .m-l-lg { margin-left: 2rem; } .p-l-lg { padding-left: 2rem; } .m-xl { margin: 4rem; } .p-xl { padding: 4rem; } .m-t-xl { margin-top: 4rem; } .p-t-xl { padding-top: 4rem; } .m-r-xl { margin-right: 4rem; } .p-r-xl { padding-right: 4rem; } .m-b-xl { margin-bottom: 4rem; } .p-b-xl { padding-bottom: 4rem; } .m-l-xl { margin-left: 4rem; } .p-l-xl { padding-left: 4rem; } .m-xxl { margin: 8rem; } .p-xxl { padding: 8rem; } .m-t-xxl { margin-top: 8rem; } .p-t-xxl { padding-top: 8rem; } .m-r-xxl { margin-right: 8rem; } .p-r-xxl { padding-right: 8rem; } .m-b-xxl { margin-bottom: 8rem; } .p-b-xxl { padding-bottom: 8rem; } .m-l-xxl { margin-left: 8rem; } .p-l-xxl { padding-left: 8rem; }
…and is configurable by changing the values of
$sizeUnit
(rem, em, px),$marginKey
('m', 'marg', 'margin', etc),$paddingKey
('p', 'pad', 'padding', etc),$separator
('-', '_', '' for none, etc) and$sizes
(whatever keys/values you need).
I suggest to change sass variabel $size
to $spacing-sizes
or another name, cause sass variable $size
already used by bulma.
Thanks you in advance @furey, it helps me.
Thanks, but I extend it a bit.
$sizeUnit: rem;
$marginKey: "m";
$paddingKey: "p";
$separator: "-";
$sizes: (("none", 0), ("xxs", 0.125), ("xs", 0.25), ("sm", 0.5), ("md", 1), ("lg", 2), ("xl", 4), ("xxl", 8));
$positions: (("t", "top"), ("r", "right"), ("b", "bottom"), ("l", "left"), ("x", "x"), ("y", "y"));
@function sizeValue($key, $value) {
@return if($key == "none", 0, $value + $sizeUnit);
}
@each $size in $sizes {
$sizeKey: nth($size, 1);
$sizeValue: nth($size, 2);
.#{$marginKey}#{$separator}#{$sizeKey} {
margin: sizeValue($sizeKey, $sizeValue);
}
.#{$paddingKey}#{$separator}#{$sizeKey} {
padding: sizeValue($sizeKey, $sizeValue);
}
@each $position in $positions {
$posKey: nth($position, 1);
$posValue: nth($position, 2);
.#{$marginKey}#{$separator}#{$posKey}#{$separator}#{$sizeKey} {
@if $posValue == "x" {
margin-left: sizeValue($sizeKey, $sizeValue);
margin-right: sizeValue($sizeKey, $sizeValue);
} @else if $posValue == "y" {
margin-top: sizeValue($sizeKey, $sizeValue);
margin-bottom: sizeValue($sizeKey, $sizeValue);
} @else {
margin-#{$posValue}: sizeValue($sizeKey, $sizeValue);
}
}
.#{$paddingKey}#{$separator}#{$posKey}#{$separator}#{$sizeKey} {
@if $posValue == "x" {
padding-left: sizeValue($sizeKey, $sizeValue);
padding-right: sizeValue($sizeKey, $sizeValue);
} @else if $posValue == "y" {
padding-top: sizeValue($sizeKey, $sizeValue);
padding-bottom: sizeValue($sizeKey, $sizeValue);
} @else {
padding-#{$posValue}: sizeValue($sizeKey, $sizeValue);
}
}
}
}
Also, I might remove one certain separator and tweak it a bit,
$sizeUnit: rem;
$marginKey: "m";
$paddingKey: "p";
$separator: "-";
$sizes: (("0", 0), ("xxs", 0.125), ("xs", 0.25), ("sm", 0.5), ("md", 1), ("lg", 2), ("xl", 4), ("xxl", 8));
$positions: (("t", "top"), ("r", "right"), ("b", "bottom"), ("l", "left"), ("x", "x"), ("y", "y"));
@function sizeValue($key, $value) {
@return if($key == "0", 0, $value + $sizeUnit);
}
@each $size in $sizes {
$sizeKey: nth($size, 1);
$sizeValue: nth($size, 2);
.#{$marginKey}#{$separator}#{$sizeKey} {
margin: sizeValue($sizeKey, $sizeValue);
}
.#{$paddingKey}#{$separator}#{$sizeKey} {
padding: sizeValue($sizeKey, $sizeValue);
}
@each $position in $positions {
$posKey: nth($position, 1);
$posValue: nth($position, 2);
.#{$marginKey}#{$posKey}#{$separator}#{$sizeKey} {
@if $posValue == "x" {
margin-left: sizeValue($sizeKey, $sizeValue);
margin-right: sizeValue($sizeKey, $sizeValue);
} @else if $posValue == "y" {
margin-top: sizeValue($sizeKey, $sizeValue);
margin-bottom: sizeValue($sizeKey, $sizeValue);
} @else {
margin-#{$posValue}: sizeValue($sizeKey, $sizeValue);
}
}
.#{$paddingKey}#{$posKey}#{$separator}#{$sizeKey} {
@if $posValue == "x" {
padding-left: sizeValue($sizeKey, $sizeValue);
padding-right: sizeValue($sizeKey, $sizeValue);
} @else if $posValue == "y" {
padding-top: sizeValue($sizeKey, $sizeValue);
padding-bottom: sizeValue($sizeKey, $sizeValue);
} @else {
padding-#{$posValue}: sizeValue($sizeKey, $sizeValue);
}
}
}
}
Yes spacing is needed for boosting productivity and consistency. Yes having n classes like mrt-10 is bloatware. So, no space helper or bloatware classes ?
With a thoughtful thinking we can get something in between for a win-win.
Based on the nomenclature of bulma alone, I would expect to have something along these lines:
(has-padding
and has-margin
) or (has-space
)
we don't need much more than that. The margin and padding would be component-controllable and breakpointable, wait ... whaaat?
Elements/components can have an optional "library provided" value for padding/margins. (Like currently the hero component) or have the custom "provided default space" (most likely almost all elements/component will have the default one)
then developers can use it like:
<section class="my-section has-space"></section> * have default margin/padding and adjust on different breakpoints
and if needed to override, can do:
.has-space.is-desktop { ... custom spacing for dekstop breakpoints... }
.my-section.has-space { ... custom spacing for my-section element ...}
or
.my-section.has-space.is-desktop { ... custom spacing for my-section element for desktop ... }
etc... you get the idea.
For example, right now a hero component will have margin/padding unknown to the developer. So if I want to stay consistent on next section on a p to have same space on the left, I would need to: a) figure out all the margin/padding rules for the component. b) remove the component pad/marg and make a custom/personal one. which may break on different breakpoint and would need lots of testing.
There are block and inline elements, the has-space
should only be applicable to block elements. (at least on first iteration) the idea should be to get consistent spacing on different component/pages without lots of effort.
Take a look at this example (highlighted in yellow)
the structural padding is way inside in the elements and is not flowing with the structure. This is not ok. We should aim for basic/base structures that doesn't explode if we update it's content.
If the container of those anchor
controller the spacing that problem would never happen, and that's great opportunity for a framework to provide us the devs the tools to avoid those kind of problems.
In my opinion of years (decades?) doing html/css, removing the padding of an a
element should not destroy the structure of the document
I can totally try to build a proof of concept if the authors of bulma are interested.
Spacing is an important concept when doing UX/UI. I'm not in favor of html design and bloatware classes, and that's why I also think we can greatly benefit from something well designed around it.
nevermind, this does already exist with section.
A few thoughts. I came here because I needed to add vertical spacing between sections of a complex form.
First of all, quotes like this:
This strong attitude(thought) is bad for bulma!. Not listening to community is almost main reason of any product dying. You've been warned!
...are highly disrespectful. Comments like these are the reason why open source maintainers are fed up with their projects and overly demanding (non-paying) user base. If a project starts adding everything that the community demands, it usually ends up as a bloated collection of incoherent components. I'm not saying that spacing helpers are such a thing, but it is the project leaders' decision what they want to integrate into the core and what they don't want. If they think it doesn't fit in the core, then add it to projects like "bulma-helpers" or the "helpers" directory of your own project.
In my experience, good open source projects stay good over the years due to the features they reject, not due to the features they add.
Now to the spacing itself: If we start adding classes like "mt-10" for 10 px top margin, then where is the difference to setting
style="margin-top: 10px;"
? If there should be a set of spacing helpers, it should be abstract, so that it can be adjusted and scaled depending on the project and the responsive environment. A system with indicators like "space-top-(s|m|l|xl)" or a number based system similar to the "is-size-(1..7)" is much more useful. I want to influence the vertical "rhythm" of my page elements, but I want that rhythm to feel consistent on all pages. Absolute pixel sizes in class names do not achieve that goal.But in the end, if I want to style sections of my page in a consistent style specific to my page, then that's exactly what classes + CSS are made for. There's nothing bad about adding
class="form-section"
to my form sections and then adding a.form-section { ... }
block in my project CSS file.Or - of course - you can include one of the many already existing spacing helpers. They're one include away.
I understand what you are saying about open-source. But unless the project you're working on solves a problem that's huge in the community, you are more or less copying someone else work. And from a developer perspective, what does Bulma solve that Bootstrap cannot solve? I would say that it has not a Jquery dependency and so you can use it with, for example, React projects; but that's kind of it, and there are very good React/Bootstrap solutions out there. You can also choose just what you need from Bootstrap, so that you don't have very big modules around. And so on. Personally, if I'm about to do a fast project, I may not want to use Bootstrap, but something tailored for a small project, that can be Bulma. But without helpers, or at the first difficulties, if I have to employ external solutions because my first solution cannot solve that, I would go anyway for the big player, just because it does what I want, and I also know it. That's my dev perspective and the reason I will probably never use Bulma. Other people may have a different opinion and that's ok. I hope the best of luck for you.
I like @truongnmt's a lot. I created a version of it that uses rem
and includes .5
increments:
$sizes: (0, 1, 2, 3, 4, 5, 6, 7, 8);
$positions: ('top', 'left', 'bottom', 'right');
@each $size in $sizes {
@each $position in $positions {
.m#{str-slice($position, 0, 1)}-#{$size} {
margin-#{$position}: $size + rem;
}
.m#{str-slice($position, 0, 1)}-#{$size}5 {
margin-#{$position}: ($size + .5) + rem;
}
.p#{str-slice($position, 0, 1)}-#{$size} {
padding-#{$position}: $size + rem;
}
.p#{str-slice($position, 0, 1)}-#{$size}5 {
padding-#{$position}: ($size + .5) + rem;
}
}
}
The above produces the following CSS:
.mt-0 {margin-top: 0rem;}
.mt-05 {margin-top: 0.5rem;}
.pt-0 {padding-top: 0rem;}
.pt-05 {padding-top: 0.5rem;}
.ml-0 {margin-left: 0rem;}
.ml-05 {margin-left: 0.5rem;}
.pl-0 {padding-left: 0rem;}
.pl-05 {padding-left: 0.5rem;}
.mb-0 {margin-bottom: 0rem;}
.mb-05 {margin-bottom: 0.5rem;}
.pb-0 {padding-bottom: 0rem;}
.pb-05 {padding-bottom: 0.5rem;}
.mr-0 {margin-right: 0rem;}
.mr-05 {margin-right: 0.5rem;}
.pr-0 {padding-right: 0rem;}
.pr-05 {padding-right: 0.5rem;}
.mt-1 {margin-top: 1rem;}
.mt-15 {margin-top: 1.5rem;}
.pt-1 {padding-top: 1rem;}
.pt-15 {padding-top: 1.5rem;}
.ml-1 {margin-left: 1rem;}
.ml-15 {margin-left: 1.5rem;}
.pl-1 {padding-left: 1rem;}
.pl-15 {padding-left: 1.5rem;}
.mb-1 {margin-bottom: 1rem;}
.mb-15 {margin-bottom: 1.5rem;}
.pb-1 {padding-bottom: 1rem;}
.pb-15 {padding-bottom: 1.5rem;}
.mr-1 {margin-right: 1rem;}
.mr-15 {margin-right: 1.5rem;}
.pr-1 {padding-right: 1rem;}
.pr-15 {padding-right: 1.5rem;}
.mt-2 {margin-top: 2rem;}
.mt-25 {margin-top: 2.5rem;}
.pt-2 {padding-top: 2rem;}
.pt-25 {padding-top: 2.5rem;}
.ml-2 {margin-left: 2rem;}
.ml-25 {margin-left: 2.5rem;}
.pl-2 {padding-left: 2rem;}
.pl-25 {padding-left: 2.5rem;}
.mb-2 {margin-bottom: 2rem;}
.mb-25 {margin-bottom: 2.5rem;}
.pb-2 {padding-bottom: 2rem;}
.pb-25 {padding-bottom: 2.5rem;}
.mr-2 {margin-right: 2rem;}
.mr-25 {margin-right: 2.5rem;}
.pr-2 {padding-right: 2rem;}
.pr-25 {padding-right: 2.5rem;}
.mt-3 {margin-top: 3rem;}
.mt-35 {margin-top: 3.5rem;}
.pt-3 {padding-top: 3rem;}
.pt-35 {padding-top: 3.5rem;}
.ml-3 {margin-left: 3rem;}
.ml-35 {margin-left: 3.5rem;}
.pl-3 {padding-left: 3rem;}
.pl-35 {padding-left: 3.5rem;}
.mb-3 {margin-bottom: 3rem;}
.mb-35 {margin-bottom: 3.5rem;}
.pb-3 {padding-bottom: 3rem;}
.pb-35 {padding-bottom: 3.5rem;}
.mr-3 {margin-right: 3rem;}
.mr-35 {margin-right: 3.5rem;}
.pr-3 {padding-right: 3rem;}
.pr-35 {padding-right: 3.5rem;}
.mt-4 {margin-top: 4rem;}
.mt-45 {margin-top: 4.5rem;}
.pt-4 {padding-top: 4rem;}
.pt-45 {padding-top: 4.5rem;}
.ml-4 {margin-left: 4rem;}
.ml-45 {margin-left: 4.5rem;}
.pl-4 {padding-left: 4rem;}
.pl-45 {padding-left: 4.5rem;}
.mb-4 {margin-bottom: 4rem;}
.mb-45 {margin-bottom: 4.5rem;}
.pb-4 {padding-bottom: 4rem;}
.pb-45 {padding-bottom: 4.5rem;}
.mr-4 {margin-right: 4rem;}
.mr-45 {margin-right: 4.5rem;}
.pr-4 {padding-right: 4rem;}
.pr-45 {padding-right: 4.5rem;}
.mt-5 {margin-top: 5rem;}
.mt-55 {margin-top: 5.5rem;}
.pt-5 {padding-top: 5rem;}
.pt-55 {padding-top: 5.5rem;}
.ml-5 {margin-left: 5rem;}
.ml-55 {margin-left: 5.5rem;}
.pl-5 {padding-left: 5rem;}
.pl-55 {padding-left: 5.5rem;}
.mb-5 {margin-bottom: 5rem;}
.mb-55 {margin-bottom: 5.5rem;}
.pb-5 {padding-bottom: 5rem;}
.pb-55 {padding-bottom: 5.5rem;}
.mr-5 {margin-right: 5rem;}
.mr-55 {margin-right: 5.5rem;}
.pr-5 {padding-right: 5rem;}
.pr-55 {padding-right: 5.5rem;}
.mt-6 {margin-top: 6rem;}
.mt-65 {margin-top: 6.5rem;}
.pt-6 {padding-top: 6rem;}
.pt-65 {padding-top: 6.5rem;}
.ml-6 {margin-left: 6rem;}
.ml-65 {margin-left: 6.5rem;}
.pl-6 {padding-left: 6rem;}
.pl-65 {padding-left: 6.5rem;}
.mb-6 {margin-bottom: 6rem;}
.mb-65 {margin-bottom: 6.5rem;}
.pb-6 {padding-bottom: 6rem;}
.pb-65 {padding-bottom: 6.5rem;}
.mr-6 {margin-right: 6rem;}
.mr-65 {margin-right: 6.5rem;}
.pr-6 {padding-right: 6rem;}
.pr-65 {padding-right: 6.5rem;}
.mt-7 {margin-top: 7rem;}
.mt-75 {margin-top: 7.5rem;}
.pt-7 {padding-top: 7rem;}
.pt-75 {padding-top: 7.5rem;}
.ml-7 {margin-left: 7rem;}
.ml-75 {margin-left: 7.5rem;}
.pl-7 {padding-left: 7rem;}
.pl-75 {padding-left: 7.5rem;}
.mb-7 {margin-bottom: 7rem;}
.mb-75 {margin-bottom: 7.5rem;}
.pb-7 {padding-bottom: 7rem;}
.pb-75 {padding-bottom: 7.5rem;}
.mr-7 {margin-right: 7rem;}
.mr-75 {margin-right: 7.5rem;}
.pr-7 {padding-right: 7rem;}
.pr-75 {padding-right: 7.5rem;}
.mt-8 {margin-top: 8rem;}
.mt-85 {margin-top: 8.5rem;}
.pt-8 {padding-top: 8rem;}
.pt-85 {padding-top: 8.5rem;}
.ml-8 {margin-left: 8rem;}
.ml-85 {margin-left: 8.5rem;}
.pl-8 {padding-left: 8rem;}
.pl-85 {padding-left: 8.5rem;}
.mb-8 {margin-bottom: 8rem;}
.mb-85 {margin-bottom: 8.5rem;}
.pb-8 {padding-bottom: 8rem;}
.pb-85 {padding-bottom: 8.5rem;}
.mr-8 {margin-right: 8rem;}
.mr-85 {margin-right: 8.5rem;}
.pr-8 {padding-right: 8rem;}
.pr-85 {padding-right: 8.5rem;}
Thank all of you here for your interest and contributions. It's heartening and useful.
@dreki
Thanks for nice styles, but I realized that the styles are not responsive so it would be great to add different sizes according the Bulma breakpoints.
@jgthms How about extending the section.sass file with 2 helpers: .is-horizontal
and .is-vertical
, which would simply allow to remove horizontal or vertical padding?
Like
$section-padding-vertical: 3rem !default
$section-padding-horizontal: 1.5rem !default
$section-padding:$section-padding-vertical $section-padding-horizontal !default
$section-padding-medium-vertical: 9rem !default
$section-padding-medium-horizontal: $section-padding-horizontal !default
$section-padding-medium:$section-padding-medium-vertical $section-padding-medium-horizontal !default
$section-padding-large-vertical: 18rem !default
$section-padding-large-horizontal: $section-padding-horizontal !default
$section-padding-large: $section-padding-large-horizontal $section-padding-large-horizontal !default
.section
padding: $section-padding
&.is-vertical
padding: $section-padding-vertical 0
&.is-horizontal
padding: 0 $section-padding-horizontal
// Responsiveness
+desktop
// Sizes
&.is-medium
padding: $section-padding-medium
&.is-vertical
padding: $section-padding-medium-vertical 0
&.is-horizontal
padding: 0 $section-padding-medium-horizontal
&.is-large
padding: $section-padding-large
&.is-vertical
padding: $section-padding-large-vertical 0
&.is-horizontal
padding: 0 $section-padding-large-horizontal
Then one could definitely play around .section
utility without having dirty custom classes.
Names could be discussed of course (eg. .horizontal-section
and .vertical-section
may be clearer to read).
Aren't inline styles considered bad practice and of relatively worse performance compared to CSS classes?
Actually, looking at a single rule, they're supposed to be a little faster to process, especially for older browsers, but if you start using them everywhere, you loose the benefit of reusing classes and caching CSS, so you end up with worst performance. It's also difficult to manage CSS neatly when you start to spread it all around.
For the current issue, I'm just starting using Buefy/Bulma for a lightweight project and need padding for a Vuejs component. I think I'll try mapping Bulma's $size-X values to CSS variables in my main file as global references, then I will attach a scoped style to the component for padding, referring to the global CSS variable. I'll see how far it takes me in the long run.
Re-opening. This will probably be added in the next release. I just need to figure out the best approach, as there are a few solutions shared here.
m-
and p-
.t
top b
bottom l
left r
right h
horizontal v
vertical, so mv-
would be a shortcut for both margin-left
and margin-right
is-small
, is-normal
, is-medium
, is-large
but they're quite long. It seems xs
, sm
, md
, lg
are preferred but it would be a new naming convention in Bulmam-0
m-1
m-2
until 6 should workm-0-mobile
and m-2-tablet
that could be combinedAll of this would be configurable, but having a decent default would be benefitial.
@jgthms That sounds awesome! Spacing helpers are literally the only thing I immediately add to any new Bulma setup, so having it ready to go out of the box would be fabulous.
Yeah, building out some pages now and I find myself in need of some extra space!
Looking forward to what you come up with.
- Margin and padding could be abbreviated to
m-
andp-
.- Directions could be
t
topb
bottoml
leftr
righth
horizontalv
vertical, somv-
would be a shortcut for bothmargin-left
andmargin-right
Just to confirm, is vertical (v
) example correct when you say left and right padding? I'd expect mh-
be horizontal aka left/right and mv-
be top/bottom.
Similar helpers as you likely know use axis, mx-
and my-
which make it easy to represent the directions.
If it wasn't a mistake, it could make sense that you are "vertically" padding and therefore shrinking the width with left and right padding, but it'll be easily confused given the other libraries that consider vertical to be top/bottom.
I'd expect
mh-
be horizontal aka left/right andmv-
be top/bottom.
Yes, I got it wrong. mv
is top/bottom
and mh
is left/right
.
I second the use of mx my px py
instead of mh mv ph pv
I will probably avoid mx
for 2 reasons:
x
is a "cross" and Flexbox already has terminology for a "cross axis", so there could be confusion as to which direction mx
goes, especially since you can flip the axis in Flexbox
The x and y axis are not always horizontal and vertical respectively. If a third dimension is introduced (and there is one in CSS with the z-index
), then it can look like this:
Even if mx
and my
can be understood as "horizontal" and "vertical", mh
and mv
seems more natural.
@jgthms Can that be configurable? I bounce back and forth between projects using Bulma and Tailwind every day and that would probably drive me bonkers.
@jgthms Can that be configurable
Sure. Will see what I can do.
If you enjoy to use pixels instead of ems-rems or vh-vw's, I created a package named bulma-spacing by using Bulma's naming syntax and we can merge if you want. I know ml-5
is way shorter than has-margin-left-5
but It creates consistency in application IMO. @jgthms
In spirit of bulma already using a small set of modifiers, I'd also like to see a default "handles most situations well" margin/padding on many of the containers. We can then have a small subset of spacing modifiers like is-small-space
, is-medium-space
, is-large-space
, is-no-space
, etc... we can reduce a bit of the bloat this way by having defaults that are easily modified instead of introducing a large array of spacing classes. More often than not, I only need an extra 30-60px of spacing below my elements. Another benefit of opting for this technique would be more standardized layouts. We give up a little bit of control, but it helps maintain a clean layout. Let me know your thoughts.
@zackperdue The name and amount of spacing utilities will be configurable. Here's an initial snippet:
$shortcuts: ("margin": "m", "padding": "p") !default
$directions: ("top": "t", "right": "r", "bottom": "b", "left": "l") !default
$horizontal: "x" !default
$vertical: "y" !default
$values: ("0": 0, "1": 0.25rem, "2": 0.5rem, "3": 0.75rem, "4": 1rem, "5": 1.5rem, "6": 3rem) !default
If you only wanted "small", "medium" and "large", you could customize it this way:
$values: ("small": 15px, "medium": 30px, "large": 60px)
Awesome ! Customizable helpers is definitely the best solution!
I have this on my latest project. Here is my code:
$sizes: (0,10,15,20,25,30,50); $positions: ('top','left','bottom','right'); @each $size in $sizes { .u-m-#{$size} { margin: $size + px; } .u-p-#{$size} { padding: $size + px; } }
You would use it like this
<div class="m-t-10">This div has top margin 10px</div>
You can add a scaling factor and scale it each size.
I think you forgot $positions
in your loop.
@zackperdue The name and amount of spacing utilities will be configurable. Here's an initial snippet:
$shortcuts: ("margin": "m", "padding": "p") !default $directions: ("top": "t", "right": "r", "bottom": "b", "left": "l") !default $horizontal: "x" !default $vertical: "y" !default $values: ("0": 0, "1": 0.25rem, "2": 0.5rem, "3": 0.75rem, "4": 1rem, "5": 1.5rem, "6": 3rem) !default
If you only wanted "small", "medium" and "large", you could customize it this way:
$values: ("small": 15px, "medium": 30px, "large": 60px)
will horizontal and vertical be configurable too? Like if it's set to false, would it be left out of the generation? That would be great and very composable. Based on the fact that you could want only one direction and no x/y spacers.
Thank you, just jumped into this on Google. I'm hoping for the next release.
will horizontal and vertical be configurable too? Like if it's set to false, would it be left out of the generation?
Yes. You can set it to null
. Here is a demonstration: https://twitter.com/jgthms/status/1260509712208015361
Building upon @ilicmarko, @furey, and @patarapolw 's comments I love bulma and I agree that spacing classes will bloat it. I feel that most people are used to bootstrap style spacing classes. So, I created bootstrap styled spacing helpers. I hope it helps 🙂
Here is the css:
.m-0 { margin: 0; }
.p-0 { padding: 0; }
.mt-0 { margin-top: 0; }
.pt-0 { padding-top: 0; }
.mr-0 { margin-right: 0; }
.pr-0 { padding-right: 0; }
.mb-0 { margin-bottom: 0; }
.pb-0 { padding-bottom: 0; }
.ml-0 { margin-left: 0; }
.pl-0 { padding-left: 0; }
.mx-0 { margin-left: 0; margin-right: 0; }
.px-0 { padding-left: 0; padding-right: 0; }
.my-0 { margin-top: 0; margin-bottom: 0; }
.py-0 { padding-top: 0; padding-bottom: 0; }
.m-auto { margin: auto; }
.p-auto { padding: auto; }
.mt-auto { margin-top: auto; }
.pt-auto { padding-top: auto; }
.mr-auto { margin-right: auto; }
.pr-auto { padding-right: auto; }
.mb-auto { margin-bottom: auto; }
.pb-auto { padding-bottom: auto; }
.ml-auto { margin-left: auto; }
.pl-auto { padding-left: auto; }
.mx-auto { margin-left: auto; margin-right: auto; }
.px-auto { padding-left: auto; padding-right: auto; }
.my-auto { margin-top: auto; margin-bottom: auto; }
.py-auto { padding-top: auto; padding-bottom: auto; }
.m-1 { margin: 0.25rem; }
.p-1 { padding: 0.25rem; }
.mt-1 { margin-top: 0.25rem; }
.pt-1 { padding-top: 0.25rem; }
.mr-1 { margin-right: 0.25rem; }
.pr-1 { padding-right: 0.25rem; }
.mb-1 { margin-bottom: 0.25rem; }
.pb-1 { padding-bottom: 0.25rem; }
.ml-1 { margin-left: 0.25rem; }
.pl-1 { padding-left: 0.25rem; }
.mx-1 { margin-left: 0.25rem; margin-right: 0.25rem; }
.px-1 { padding-left: 0.25rem; padding-right: 0.25rem; }
.my-1 { margin-top: 0.25rem; margin-bottom: 0.25rem; }
.py-1 { padding-top: 0.25rem; padding-bottom: 0.25rem; }
.m-2 { margin: 0.5rem; }
.p-2 { padding: 0.5rem; }
.mt-2 { margin-top: 0.5rem; }
.pt-2 { padding-top: 0.5rem; }
.mr-2 { margin-right: 0.5rem; }
.pr-2 { padding-right: 0.5rem; }
.mb-2 { margin-bottom: 0.5rem; }
.pb-2 { padding-bottom: 0.5rem; }
.ml-2 { margin-left: 0.5rem; }
.pl-2 { padding-left: 0.5rem; }
.mx-2 { margin-left: 0.5rem; margin-right: 0.5rem; }
.px-2 { padding-left: 0.5rem; padding-right: 0.5rem; }
.my-2 { margin-top: 0.5rem; margin-bottom: 0.5rem; }
.py-2 { padding-top: 0.5rem; padding-bottom: 0.5rem; }
.m-3 { margin: 1rem; }
.p-3 { padding: 1rem; }
.mt-3 { margin-top: 1rem; }
.pt-3 { padding-top: 1rem; }
.mr-3 { margin-right: 1rem; }
.pr-3 { padding-right: 1rem; }
.mb-3 { margin-bottom: 1rem; }
.pb-3 { padding-bottom: 1rem; }
.ml-3 { margin-left: 1rem; }
.pl-3 { padding-left: 1rem; }
.mx-3 { margin-left: 1rem; margin-right: 1rem; }
.px-3 { padding-left: 1rem; padding-right: 1rem; }
.my-3 { margin-top: 1rem; margin-bottom: 1rem; }
.py-3 { padding-top: 1rem; padding-bottom: 1rem; }
.m-4 { margin: 1.5rem; }
.p-4 { padding: 1.5rem; }
.mt-4 { margin-top: 1.5rem; }
.pt-4 { padding-top: 1.5rem; }
.mr-4 { margin-right: 1.5rem; }
.pr-4 { padding-right: 1.5rem; }
.mb-4 { margin-bottom: 1.5rem; }
.pb-4 { padding-bottom: 1.5rem; }
.ml-4 { margin-left: 1.5rem; }
.pl-4 { padding-left: 1.5rem; }
.mx-4 { margin-left: 1.5rem; margin-right: 1.5rem; }
.px-4 { padding-left: 1.5rem; padding-right: 1.5rem; }
.my-4 { margin-top: 1.5rem; margin-bottom: 1.5rem; }
.py-4 { padding-top: 1.5rem; padding-bottom: 1.5rem; }
.m-5 { margin: 3rem; }
.p-5 { padding: 3rem; }
.mt-5 { margin-top: 3rem; }
.pt-5 { padding-top: 3rem; }
.mr-5 { margin-right: 3rem; }
.pr-5 { padding-right: 3rem; }
.mb-5 { margin-bottom: 3rem; }
.pb-5 { padding-bottom: 3rem; }
.ml-5 { margin-left: 3rem; }
.pl-5 { padding-left: 3rem; }
.mx-5 { margin-left: 3rem; margin-right: 3rem; }
.px-5 { padding-left: 3rem; padding-right: 3rem; }
.my-5 { margin-top: 3rem; margin-bottom: 3rem; }
.py-5 { padding-top: 3rem; padding-bottom: 3rem; }
Here is the scss
$marginKey: "m";
$paddingKey: "p";
$spacer: 1;
$sizeUnit: rem;
$separator: "-";
$sizes: (
("0", 0),
("auto", auto),
("1", $spacer * 0.25),
("2", $spacer * 0.5),
("3", $spacer),
("4", $spacer * 1.5),
("5", $spacer * 3),
);
$positions: (
("t", "top"),
("r", "right"),
("b", "bottom"),
("l", "left"),
("x", "x"),
("y", "y")
);
@function sizeValue($key, $value) {
@if ($key == "0") {
@return 0;
} @else if ($key == "auto") {
@return auto;
} @else {
@return $value + $sizeUnit;
}
}
@each $size in $sizes {
$sizeKey: nth($size, 1);
$sizeValue: nth($size, 2);
.#{$marginKey}#{$separator}#{$sizeKey} {
margin: sizeValue($sizeKey, $sizeValue);
}
.#{$paddingKey}#{$separator}#{$sizeKey} {
padding: sizeValue($sizeKey, $sizeValue);
}
@each $position in $positions {
$posKey: nth($position, 1);
$posValue: nth($position, 2);
.#{$marginKey}#{$posKey}#{$separator}#{$sizeKey} {
@if $posValue == "x" {
margin-left: sizeValue($sizeKey, $sizeValue);
margin-right: sizeValue($sizeKey, $sizeValue);
} @else if $posValue == "y" {
margin-top: sizeValue($sizeKey, $sizeValue);
margin-bottom: sizeValue($sizeKey, $sizeValue);
} @else {
margin-#{$posValue}: sizeValue($sizeKey, $sizeValue);
}
}
.#{$paddingKey}#{$posKey}#{$separator}#{$sizeKey} {
@if $posValue == "x" {
padding-left: sizeValue($sizeKey, $sizeValue);
padding-right: sizeValue($sizeKey, $sizeValue);
} @else if $posValue == "y" {
padding-top: sizeValue($sizeKey, $sizeValue);
padding-bottom: sizeValue($sizeKey, $sizeValue);
} @else {
padding-#{$posValue}: sizeValue($sizeKey, $sizeValue);
}
}
}
}
The scss file can be modified by adding !important
to the sizeValue
function
@function sizeValue($key, $value) {
@if ($key == "0") {
@return 0 + " " + !important;
} @else if ($key == "auto") {
@return auto + " " + !important;
} @else {
@return $value + $sizeUnit + " " + !important;
}
}
@jgthms I saw your tweet about spacing helper..!!!! it's great. when it'll be releasing..????? I need spacing very badly..!!!!! please add it as soon as possible.
Also, anyone can use: https://github.com/kaangokdemir/bulma-spacing
Great addition!
I'm not sure how to handle responsiveness, in order to have mobile/tablet/desktop/widescreen/fullhd version of each spacing helper. If following the above approach, you would have m-0-mobile and m-2-tablet that could be combined.
Different spacing for each breakpoint is a very common thing in our projects. It would be a very useful feature too.
moving to Tailwind, at last
Now that we have spacing helpers, it is a logic move to make them responsive :)
responsive scss spacing helpers
@each $property, $shortcut in $spacing-shortcuts {
@each $name, $value in $spacing-values {
// Cardinal directions
@each $direction, $suffix in $spacing-directions {
@include mobile {
.#{$shortcut}#{$suffix}-#{$name}-mobile {
#{$property}-#{$direction}: $value !important;
}
}
@include tablet {
.#{$shortcut}#{$suffix}-#{$name}-tablet {
#{$property}-#{$direction}: $value !important;
}
}
@include touch {
.#{$shortcut}#{$suffix}-#{$name}-touch {
#{$property}-#{$direction}: $value !important;
}
}
@include desktop {
.#{$shortcut}#{$suffix}-#{$name}-desktop {
#{$property}-#{$direction}: $value !important;
}
}
@include widescreen {
.#{$shortcut}#{$suffix}-#{$name}-widescreen {
#{$property}-#{$direction}: $value !important;
}
}
@include fullhd {
.#{$shortcut}#{$suffix}-#{$name}-fullhd {
#{$property}-#{$direction}: $value !important;
}
}
}
// Horizontal axis
@if $spacing-horizontal != null {
@include mobile {
.#{$shortcut}#{$spacing-horizontal}-#{$name}-mobile {
#{$property}-left: $value !important;
#{$property}-right: $value !important;
}
}
@include tablet {
.#{$shortcut}#{$spacing-horizontal}-#{$name}-tablet {
#{$property}-left: $value !important;
#{$property}-right: $value !important;
}
}
@include touch {
.#{$shortcut}#{$spacing-horizontal}-#{$name}-touch {
#{$property}-left: $value !important;
#{$property}-right: $value !important;
}
}
@include desktop {
.#{$shortcut}#{$spacing-horizontal}-#{$name}-desktop {
#{$property}-left: $value !important;
#{$property}-right: $value !important;
}
}
@include widescreen {
.#{$shortcut}#{$spacing-horizontal}-#{$name}-widescreen {
#{$property}-left: $value !important;
#{$property}-right: $value !important;
}
}
@include fullhd {
.#{$shortcut}#{$spacing-horizontal}-#{$name}-fullhd {
#{$property}-left: $value !important;
#{$property}-right: $value !important;
}
}
}
// Vertical axis
@if $spacing-vertical != null {
@include mobile {
.#{$shortcut}#{$spacing-vertical}-#{$name}-mobile {
#{$property}-top: $value !important;
#{$property}-bottom: $value !important;
}
}
@include tablet {
.#{$shortcut}#{$spacing-vertical}-#{$name}-tablet {
#{$property}-top: $value !important;
#{$property}-bottom: $value !important;
}
}
@include touch {
.#{$shortcut}#{$spacing-vertical}-#{$name}-touch {
#{$property}-top: $value !important;
#{$property}-bottom: $value !important;
}
}
@include desktop {
.#{$shortcut}#{$spacing-vertical}-#{$name}-desktop {
#{$property}-top: $value !important;
#{$property}-bottom: $value !important;
}
}
@include widescreen {
.#{$shortcut}#{$spacing-vertical}-#{$name}-widescreen {
#{$property}-top: $value !important;
#{$property}-bottom: $value !important;
}
}
@include fullhd {
.#{$shortcut}#{$spacing-vertical}-#{$name}-fullhd {
#{$property}-top: $value !important;
#{$property}-bottom: $value !important;
}
}
}
}
}
Any update on #3184? It would be great to have spacing helpers responsive @jgthms
Hello, I made this gist for fun to generate all responsive spacing classes, I started from @retailify's solution. I started to make this just because I wanted to avoid the creation of too many media queries and I finished to make something maybe useless, but it has been fun to do this.
Gist with the builded css: https://gist.github.com/globdug/0ad7e53f7d33b3722a5a7553e72dafd2
// Return value from $spacing-allowed map
@function get-config($spacing, $value){
@return map-get(map-get($spacing-allowed, $spacing), $value);
}
// Choose which breakpoint to make responsive.
// If you don't need some of them, just remove it from the list.
$breakpoint-to-responsify: (
"mobile",
"tablet",
"table-only",
"touch",
"desktop",
"desktop-only",
"widescreen",
"widescreen-only",
"fullhd",
);
// Enable or disable making of specific classes
$spacing-allowed: (
"margin": (
"globally-enabled": true,
"x": true,
"y": true,
"top": true,
"right": true,
"bottom": true,
"left": true,
"0": true,
"1": true,
"2": true,
"3": true,
"4": true,
"5": true,
"6": true,
"auto": true,
),
"padding": (
"globally-enabled": true,
"x": true,
"y": true,
"top": true,
"right": true,
"bottom": true,
"left": true,
"0": true,
"1": true,
"2": true,
"3": true,
"4": true,
"5": true,
"6": true,
"auto": true,
),
);
// Loop through $spacing-shortcuts, $spacing-values and $spacing-directions
// in "helpers/spacings.sass" to make the responsive classes
@mixin loop-spacings($bp-name){
// Loop through "margin" and "padding"
@each $property, $shortcut in $spacing-shortcuts{
// Check if margin or padding is enabled
@if get-config($property, "globally-enabled"){
// Loop through spacing values 0, 1, 2, 3, 4, 5, 6, auto
@each $name, $value in $spacing-values{
// Check if value is enabled
@if get-config($property, $name){
// Make classes .m-1 etc
.#{$shortcut}-#{$name}-#{$bp_name}{
#{$property}: $value !important
}
// Make classes .m-x-1 etc
@if $spacing-horizontal != null and get-config($property, "x"){
.#{$shortcut}#{$spacing-horizontal}-#{$name}-#{$bp_name}{
#{$property}-left: $value !important;
#{$property}-right: $value !important;
}
}
// Make classes .m-y-1 etc
@if $spacing-vertical != null and get-config($property, "y"){
.#{$shortcut}#{$spacing-vertical}-#{$name}-#{$bp_name}{
#{$property}-top: $value !important;
#{$property}-bottom: $value !important;
}
}
// Loop through "top", "right", "bottom", "left"
@each $direction, $suffix in $spacing-directions{
// Check if direction is enabled
@if get-config($property, $direction){
// Make classes .mt-5-desktop etc
.#{$shortcut}#{$suffix}-#{$name}-#{$bp_name}{
#{$property}-#{$direction}: $value !important;
}
}
}
}
}
}
}
}
// Loop through $breakpoints in "utilities/initial-variables.sass"
@each $bp_name, $bp_map in $breakpoints{
// Check if we want to make classes for this breakpoint
@if index($breakpoint-to-responsify, $bp_name) != null{
@if $bp_name == "mobile"{
/* Mobile */
@include mobile{
@include loop-spacings($bp_name);
}
} @else if $bp_name == "tablet"{
/* Tablet */
@include tablet{
@include loop-spacings($bp_name);
}
} @else if $bp_name == "tablet-only"{
/* Tablet Only */
@include tablet-only{
@include loop-spacings($bp_name);
}
} @else if $bp_name == "touch"{
/* Touch */
@include touch{
@include loop-spacings($bp_name);
}
} @else if $bp_name == "desktop"{
/* Desktop */
@include desktop{
@include loop-spacings($bp_name);
}
} @else if $bp_name == "desktop-only"{
/* Desktop Only */
@include desktop-only{
@include loop-spacings($bp_name);
}
} @else if $bp_name == "widescreen"{
/* Widescreen */
@include widescreen{
@include loop-spacings($bp_name);
}
} @else if $bp_name == "widescreen-only"{
/* Widescreen Only */
@include widescreen-only{
@include loop-spacings($bp_name);
}
} @else if $bp_name == "fullhd"{
/* FullHD */
@include fullhd{
@include loop-spacings($bp_name);
}
}
}
}
Result is something like this (it depends from $spacing-allowed
map):
/* Mobile */
@media screen and (max-width: 768px) {
.m-0-mobile {
margin: 0 !important;
}
.mx-0-mobile {
margin-left: 0 !important;
margin-right: 0 !important;
}
.my-0-mobile {
margin-top: 0 !important;
margin-bottom: 0 !important;
}
.mt-0-mobile {
margin-top: 0 !important;
}
/* And so on... */
}
/* Tablet */
@media screen and (min-width: 769px), print {
.m-0-table {
margin: 0 !important;
}
/* And so on... */
}
/* Touch */
@media screen and (max-width: 1023px) { ... }
/* Desktop */
@media screen and (min-width: 1024px) { ... }
/* Desktop Only */
@media screen and (min-width: 1024px) and (max-width: 1215px) { ... }
/* Widescreen */
@media screen and (min-width: 1216px) { ... }
/* Widescreen Only */
@media screen and (min-width: 1216px) and (max-width: 1407px) { ... }
/* FullHD */
@media screen and (min-width: 1408px) { ... }
I didn't tested very well, it seems to work but I've done this while working on a new project and I need these classes. I hope can be usefull to someone and someone else can suggest better solutions... :)
@globdug Thank you so much for this - exactly what I needed!! Have you thought about submitting it to https://bulma.io/extensions/ ?
@floisloading You're welcome, I'm glad that this has been helpfull. :) I didn't thought about submitting to Bulma's extensions, it could be a good idea! :)
@globdug Thank you for this, it's really helpful.
Can you help add support for custom mobile-md
and mobile-lg
breakpoints? Here is the code: https://github.com/jgthms/bulma/issues/1677#issuecomment-457346571
@globdug Thank you for this, it's really helpful. Can you help add support for custom
mobile-md
andmobile-lg
breakpoints? Here is the code: #1677 (comment)
Ok, I have just made this repo, I hope it can be useful. https://github.com/globdug/bulma-responsive-spacing
If you want custom breakpoints read the README.md, I hope that is what you need.
I'm using Bulma for my recent projects. Really like the framework! One feature that would be really helpful is a 'spacing' helper. See e.g. https://github.com/inuitcss/inuitcss/blob/develop/utilities/_utilities.spacings.scss
With this option, you can easily add a padding or margin to specific elements like: .u-margin-top {} .u-padding-left-large {} .u-margin-right-small {} .u-padding {} .u-padding-right-none {} .u-padding-horizontal {} .u-padding-vertical-small {}
Perhaps we can also include the breakpoints into it, like the current 'responsive helpers'. That way we can e.g. set no padding on mobile devices and a top padding on desktops.
If others think this might be a useful addition, I can create a pull request to incorporate this feature.