From 39ea05a04a338ee549d739689cb2c8a9579b49e4 Mon Sep 17 00:00:00 2001
From: Thomas Citharel <tcit@tcit.fr>
Date: Thu, 4 Nov 2021 18:14:36 +0100
Subject: [PATCH] Add mixins to handle RTL languages

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
---
 js/src/App.vue                                |  1 -
 js/src/common.scss                            |  5 +-
 js/src/components/Account/ActorCard.vue       | 13 +++--
 js/src/components/Account/ActorInline.vue     |  3 +-
 js/src/components/Address/AddressInfo.vue     |  3 +-
 js/src/components/Comment/Comment.vue         | 13 +++--
 js/src/components/Comment/CommentTree.vue     |  3 +-
 .../Discussion/DiscussionComment.vue          |  5 +-
 .../Discussion/DiscussionListItem.vue         |  3 +-
 js/src/components/Editor.vue                  |  7 ++-
 js/src/components/Event/EventCard.vue         |  5 +-
 js/src/components/Event/EventListViewCard.vue |  3 +-
 js/src/components/Event/EventMap.vue          |  3 +-
 js/src/components/Event/EventMetadataItem.vue |  3 +-
 .../components/Event/EventMinimalistCard.vue  |  3 +-
 .../Event/EventParticipationCard.vue          |  5 +-
 js/src/components/Event/OrganizerPicker.vue   |  5 +-
 js/src/components/Group/GroupMemberCard.vue   |  3 +-
 js/src/components/Group/GroupSection.vue      |  5 +-
 js/src/components/NavBar.vue                  |  3 +-
 js/src/components/PictureUpload.vue           |  5 +-
 js/src/components/Post/PostListItem.vue       |  3 +-
 js/src/components/Resource/ResourceItem.vue   |  3 +-
 js/src/components/Todo/CompactTodo.vue        |  3 +-
 js/src/styles/_event-card.scss                |  6 +-
 js/src/styles/_mixins.scss                    | 55 +++++++++++++++++++
 .../views/Account/children/EditIdentity.vue   |  2 +-
 js/src/views/Discussions/Discussion.vue       |  3 +-
 js/src/views/Event/Edit.vue                   |  3 +-
 js/src/views/Event/Event.vue                  | 11 ++--
 js/src/views/Group/Group.vue                  | 19 ++++---
 js/src/views/Home.vue                         |  5 +-
 js/src/views/Posts/Edit.vue                   |  3 +-
 js/src/views/Posts/Post.vue                   |  5 +-
 js/src/views/Resources/ResourceFolder.vue     | 14 +++--
 js/src/views/Settings/Notifications.vue       |  4 +-
 36 files changed, 164 insertions(+), 74 deletions(-)
 create mode 100644 js/src/styles/_mixins.scss

diff --git a/js/src/App.vue b/js/src/App.vue
index 237ab57d9..cafe7ffe1 100644
--- a/js/src/App.vue
+++ b/js/src/App.vue
@@ -246,7 +246,6 @@ export default class App extends Vue {
 /* Icons */
 $mdi-font-path: "~@mdi/font/fonts";
 @import "~@mdi/font/scss/materialdesignicons";
-
 @import "common";
 
 #mobilizon {
diff --git a/js/src/common.scss b/js/src/common.scss
index b9c39647d..9566e8925 100644
--- a/js/src/common.scss
+++ b/js/src/common.scss
@@ -1,3 +1,4 @@
+@use "@/styles/_mixins" as *;
 @import "variables.scss";
 
 @import "~bulma";
@@ -39,7 +40,7 @@ $color-black: #000;
   border-radius: 5px;
   padding: 0.2rem;
   white-space: nowrap;
-  margin-right: 0.2rem;
+  @include margin-right(0.2rem);
 }
 
 .mention-suggestion {
@@ -48,7 +49,7 @@ $color-black: #000;
 
 .mention .mention {
   background: initial;
-  margin-right: 0;
+  @include margin-right(0);
 }
 
 .select select {
diff --git a/js/src/components/Account/ActorCard.vue b/js/src/components/Account/ActorCard.vue
index a57c2692a..2b7018e88 100644
--- a/js/src/components/Account/ActorCard.vue
+++ b/js/src/components/Account/ActorCard.vue
@@ -53,6 +53,7 @@ export default class ActorCard extends Vue {
 </style>
 
 <style lang="scss">
+@use "@/styles/_mixins" as *;
 .tooltip {
   display: block !important;
   z-index: 10000;
@@ -105,7 +106,7 @@ export default class ActorCard extends Vue {
   }
 
   &[x-placement^="right"] {
-    margin-left: 5px;
+    @include margin-left(5px);
 
     .tooltip-arrow {
       border-width: 5px 5px 5px 0;
@@ -114,13 +115,13 @@ export default class ActorCard extends Vue {
       border-bottom-color: transparent !important;
       left: -5px;
       top: calc(50% - 5px);
-      margin-left: 0;
-      margin-right: 0;
+      @include margin-left(0);
+      @include margin-right(0);
     }
   }
 
   &[x-placement^="left"] {
-    margin-right: 5px;
+    @include margin-right(5px);
 
     .tooltip-arrow {
       border-width: 5px 0 5px 5px;
@@ -129,8 +130,8 @@ export default class ActorCard extends Vue {
       border-bottom-color: transparent !important;
       right: -5px;
       top: calc(50% - 5px);
-      margin-left: 0;
-      margin-right: 0;
+      @include margin-left(0);
+      @include margin-right(0);
     }
   }
 
diff --git a/js/src/components/Account/ActorInline.vue b/js/src/components/Account/ActorInline.vue
index 3fa9af533..29fa40359 100644
--- a/js/src/components/Account/ActorInline.vue
+++ b/js/src/components/Account/ActorInline.vue
@@ -26,6 +26,7 @@ export default class ActorInline extends Vue {
 }
 </script>
 <style lang="scss" scoped>
+@use "@/styles/_mixins" as *;
 div.actor-inline {
   align-items: flex-start;
   display: inline-flex;
@@ -36,7 +37,7 @@ div.actor-inline {
     flex-basis: auto;
     flex-grow: 0;
     flex-shrink: 0;
-    margin-right: 0.5rem;
+    @include margin-right(0.5rem);
   }
   div.actor-name {
     flex-basis: auto;
diff --git a/js/src/components/Address/AddressInfo.vue b/js/src/components/Address/AddressInfo.vue
index a0ef9eadf..6675fc016 100644
--- a/js/src/components/Address/AddressInfo.vue
+++ b/js/src/components/Address/AddressInfo.vue
@@ -103,6 +103,7 @@ export default class AddressInfo extends Vue {
 }
 </script>
 <style lang="scss" scoped>
+@use "@/styles/_mixins" as *;
 address {
   font-style: normal;
   display: flex;
@@ -118,7 +119,7 @@ address {
   }
 
   span.icon {
-    padding-right: 1rem;
+    @include padding-right(1rem);
   }
 }
 </style>
diff --git a/js/src/components/Comment/Comment.vue b/js/src/components/Comment/Comment.vue
index 33fd0cc92..5ca556ea7 100644
--- a/js/src/components/Comment/Comment.vue
+++ b/js/src/components/Comment/Comment.vue
@@ -336,6 +336,7 @@ export default class Comment extends Vue {
 }
 </script>
 <style lang="scss" scoped>
+@use "@/styles/_mixins" as *;
 form.reply {
   padding-bottom: 1rem;
 }
@@ -355,7 +356,7 @@ form.reply {
   }
 
   & > small {
-    margin-left: 0.3rem;
+    @include margin-left(0.3rem);
   }
 }
 
@@ -365,14 +366,14 @@ form.reply {
 
   .editor {
     flex: 1;
-    padding-right: 10px;
+    @include padding-right(10px);
     margin-bottom: 0;
   }
 }
 
 a.comment-link {
   text-decoration: none;
-  margin-left: 5px;
+  @include margin-left(5px);
   color: $text;
   &:hover {
     text-decoration: underline;
@@ -416,7 +417,7 @@ a.comment-link {
   }
 
   .media-left {
-    margin-right: 0.5rem;
+    @include margin-right(5px);
   }
 }
 
@@ -427,7 +428,7 @@ a.comment-link {
     display: flex;
     flex-direction: column;
     align-items: center;
-    margin-right: 10px;
+    @include margin-right(10px);
 
     .vertical-border {
       width: 3px;
@@ -516,7 +517,7 @@ article {
 }
 
 .reply-action .icon {
-  padding-right: 0.4rem;
+  @include padding-right(0.4rem);
 }
 
 .visually-hidden {
diff --git a/js/src/components/Comment/CommentTree.vue b/js/src/components/Comment/CommentTree.vue
index ef1c28038..ea057784d 100644
--- a/js/src/components/Comment/CommentTree.vue
+++ b/js/src/components/Comment/CommentTree.vue
@@ -363,6 +363,7 @@ export default class CommentTree extends Vue {
 </script>
 
 <style lang="scss" scoped>
+@use "@/styles/_mixins" as *;
 form.new-comment {
   padding-bottom: 1rem;
 
@@ -373,7 +374,7 @@ form.new-comment {
 
     .field {
       flex: 1;
-      padding-right: 10px;
+      @include padding-right(10px);
       margin-bottom: 0;
 
       &.notify-participants {
diff --git a/js/src/components/Discussion/DiscussionComment.vue b/js/src/components/Discussion/DiscussionComment.vue
index 3dd5706e6..65f9d21e6 100644
--- a/js/src/components/Discussion/DiscussionComment.vue
+++ b/js/src/components/Discussion/DiscussionComment.vue
@@ -148,6 +148,7 @@ export default class DiscussionComment extends Vue {
 }
 </script>
 <style lang="scss" scoped>
+@use "@/styles/_mixins" as *;
 article.comment {
   display: flex;
   border-top: 1px solid #e9e9e9;
@@ -163,7 +164,7 @@ article.comment {
       padding: 0 1rem 0.3em;
 
       .name {
-        margin-right: auto;
+        @include margin-right(auto);
         flex: 1 1 auto;
         overflow: hidden;
 
@@ -216,7 +217,7 @@ article.comment {
         ::v-deep blockquote {
           border-left: 0.2em solid #333;
           display: block;
-          padding-left: 1em;
+          @include padding-left(1em);
         }
 
         ::v-deep p {
diff --git a/js/src/components/Discussion/DiscussionListItem.vue b/js/src/components/Discussion/DiscussionListItem.vue
index 91d6538b9..dd1558559 100644
--- a/js/src/components/Discussion/DiscussionListItem.vue
+++ b/js/src/components/Discussion/DiscussionListItem.vue
@@ -83,6 +83,7 @@ export default class DiscussionListItem extends Vue {
 }
 </script>
 <style lang="scss" scoped>
+@use "@/styles/_mixins" as *;
 .discussion-minimalist-card-wrapper {
   text-decoration: none;
   display: flex;
@@ -92,7 +93,7 @@ export default class DiscussionListItem extends Vue {
   align-items: center;
 
   .calendar-icon {
-    margin-right: 1rem;
+    @include margin-right(1rem);
   }
 
   .title-info-wrapper {
diff --git a/js/src/components/Editor.vue b/js/src/components/Editor.vue
index 9e208eacc..42143002d 100644
--- a/js/src/components/Editor.vue
+++ b/js/src/components/Editor.vue
@@ -376,6 +376,7 @@ export default class EditorComponent extends Vue {
 }
 </script>
 <style lang="scss">
+@use "@/styles/_mixins" as *;
 @import "./Editor/style.scss";
 
 $color-black: #000;
@@ -392,7 +393,7 @@ $color-white: #eee;
     border: 0;
     color: $color-black;
     padding: 0.2rem 0.5rem;
-    margin-right: 0.2rem;
+    @include margin-right(0.2rem);
     border-radius: 3px;
     cursor: pointer;
 
@@ -464,7 +465,7 @@ $color-white: #eee;
 
     ul,
     ol {
-      padding-left: 1rem;
+      @include padding-left(1rem);
     }
 
     ul {
@@ -480,7 +481,7 @@ $color-white: #eee;
     blockquote {
       border-left: 3px solid rgba($color-black, 0.1);
       color: rgba($color-black, 0.8);
-      padding-left: 0.8rem;
+      @include padding-left(0.8rem);
       font-style: italic;
 
       p {
diff --git a/js/src/components/Event/EventCard.vue b/js/src/components/Event/EventCard.vue
index 385e56136..d9010d580 100644
--- a/js/src/components/Event/EventCard.vue
+++ b/js/src/components/Event/EventCard.vue
@@ -133,6 +133,7 @@ export default class EventCard extends Vue {
 </script>
 
 <style lang="scss" scoped>
+@use "@/styles/_mixins" as *;
 @use "@/styles/_event-card";
 
 a.card {
@@ -170,7 +171,7 @@ a.card {
     position: absolute;
     top: 10px;
     right: 0;
-    margin-right: -3px;
+    @include margin-right(-3px);
     z-index: 10;
     max-width: 40%;
 
@@ -214,7 +215,7 @@ a.card {
         align-items: flex-end;
         align-self: flex-start;
         margin-bottom: 15px;
-        margin-left: 0rem;
+        @include margin-left(0);
       }
 
       & > .media-content {
diff --git a/js/src/components/Event/EventListViewCard.vue b/js/src/components/Event/EventListViewCard.vue
index 3042f4fc5..9a890f7fd 100644
--- a/js/src/components/Event/EventListViewCard.vue
+++ b/js/src/components/Event/EventListViewCard.vue
@@ -128,6 +128,7 @@ export default class EventListViewCard extends mixins(ActorMixin, EventMixin) {
 </script>
 
 <style lang="scss" scoped>
+@use "@/styles/_mixins" as *;
 article.box {
   div.content {
     padding: 5px;
@@ -148,7 +149,7 @@ article.box {
 
       div.date-component {
         flex: 0;
-        margin-right: 16px;
+        @include margin-right(16px);
       }
 
       .title {
diff --git a/js/src/components/Event/EventMap.vue b/js/src/components/Event/EventMap.vue
index 7ed79b3f2..adb332f4f 100644
--- a/js/src/components/Event/EventMap.vue
+++ b/js/src/components/Event/EventMap.vue
@@ -152,10 +152,11 @@ export default class EventMap extends Vue {
 }
 </script>
 <style lang="scss" scoped>
+@use "@/styles/_mixins" as *;
 .modal-card-head {
   justify-content: flex-end;
   button.delete {
-    margin-right: 1rem;
+    @include margin-right(1rem);
   }
 }
 
diff --git a/js/src/components/Event/EventMetadataItem.vue b/js/src/components/Event/EventMetadataItem.vue
index 332b1276a..a5c3682c8 100644
--- a/js/src/components/Event/EventMetadataItem.vue
+++ b/js/src/components/Event/EventMetadataItem.vue
@@ -131,11 +131,12 @@ export default class EventMetadataItem extends Vue {
 }
 </script>
 <style lang="scss" scoped>
+@use "@/styles/_mixins" as *;
 .card .media {
   align-items: center;
 
   & > button {
-    margin-left: 1rem;
+    @include margin-left(1rem);
   }
 }
 </style>
diff --git a/js/src/components/Event/EventMinimalistCard.vue b/js/src/components/Event/EventMinimalistCard.vue
index 631c286ae..09443f91f 100644
--- a/js/src/components/Event/EventMinimalistCard.vue
+++ b/js/src/components/Event/EventMinimalistCard.vue
@@ -131,6 +131,7 @@ export default class EventMinimalistCard extends Vue {
 }
 </script>
 <style lang="scss" scoped>
+@use "@/styles/_mixins" as *;
 @use "@/styles/_event-card";
 @import "~bulma/sass/utilities/mixins.sass";
 @import "@/variables.scss";
@@ -163,7 +164,7 @@ export default class EventMinimalistCard extends Vue {
   }
 
   .calendar-icon {
-    margin-right: 1rem;
+    @include margin-right(1rem);
   }
 
   .title-info-wrapper {
diff --git a/js/src/components/Event/EventParticipationCard.vue b/js/src/components/Event/EventParticipationCard.vue
index e549c54a6..5843d01f2 100644
--- a/js/src/components/Event/EventParticipationCard.vue
+++ b/js/src/components/Event/EventParticipationCard.vue
@@ -392,6 +392,7 @@ export default class EventParticipationCard extends mixins(
 </script>
 
 <style lang="scss" scoped>
+@use "@/styles/_mixins" as *;
 @use "@/styles/_event-card";
 @import "~bulma/sass/utilities/mixins.sass";
 
@@ -400,7 +401,7 @@ article.box {
     position: absolute;
     top: 10px;
     right: 0;
-    margin-right: -5px;
+    @include margin-left(-5px);
     z-index: 10;
     max-width: 40%;
 
@@ -516,7 +517,7 @@ article.box {
 
     figure,
     span.icon {
-      padding-right: 3px;
+      @include padding-right(3px);
     }
   }
 
diff --git a/js/src/components/Event/OrganizerPicker.vue b/js/src/components/Event/OrganizerPicker.vue
index 2a6368fd9..771e183ae 100644
--- a/js/src/components/Event/OrganizerPicker.vue
+++ b/js/src/components/Event/OrganizerPicker.vue
@@ -121,6 +121,7 @@ export default class OrganizerPicker extends Vue {
 }
 </script>
 <style lang="scss" scoped>
+@use "@/styles/_mixins" as *;
 ::v-deep .list-item {
   box-sizing: content-box;
 
@@ -133,11 +134,11 @@ export default class OrganizerPicker extends Vue {
 
       figure.image,
       span.icon.media-left {
-        margin-right: 0.5rem;
+        @include margin-right(0.5rem);
       }
 
       span.icon.media-left {
-        margin-left: -0.25rem;
+        @include margin-left(-0.25rem);
       }
     }
   }
diff --git a/js/src/components/Group/GroupMemberCard.vue b/js/src/components/Group/GroupMemberCard.vue
index 77002a359..51aa9e535 100644
--- a/js/src/components/Group/GroupMemberCard.vue
+++ b/js/src/components/Group/GroupMemberCard.vue
@@ -86,6 +86,7 @@ export default class GroupMemberCard extends Vue {
 }
 </script>
 <style lang="scss" scoped>
+@use "@/styles/_mixins" as *;
 .card {
   .card-content {
     display: flex;
@@ -113,7 +114,7 @@ export default class GroupMemberCard extends Vue {
 
     figure,
     span.icon {
-      padding-right: 3px;
+      @include padding-right(3px);
     }
   }
 }
diff --git a/js/src/components/Group/GroupSection.vue b/js/src/components/Group/GroupSection.vue
index 432ae51b2..f6e9d6658 100644
--- a/js/src/components/Group/GroupSection.vue
+++ b/js/src/components/Group/GroupSection.vue
@@ -33,6 +33,7 @@ export default class GroupSection extends Vue {
 }
 </script>
 <style lang="scss" scoped>
+@use "@/styles/_mixins" as *;
 section {
   display: flex;
   flex-direction: column;
@@ -44,7 +45,7 @@ section {
     display: flex;
     justify-content: flex-end;
     padding-bottom: 0.5rem;
-    padding-right: 0.5rem;
+    @include padding-right(0.5rem);
   }
 
   .main-slot {
@@ -68,7 +69,7 @@ div.group-section-title {
 
   ::v-deep & > a {
     align-self: center;
-    margin-right: 5px;
+    @include margin-right(5px);
     color: var(--title-color);
   }
 
diff --git a/js/src/components/NavBar.vue b/js/src/components/NavBar.vue
index 7656d2630..150ec5a59 100644
--- a/js/src/components/NavBar.vue
+++ b/js/src/components/NavBar.vue
@@ -338,6 +338,7 @@ export default class NavBar extends Vue {
 }
 </script>
 <style lang="scss" scoped>
+@use "@/styles/_mixins" as *;
 nav {
   .navbar-item {
     a.button {
@@ -370,7 +371,7 @@ nav {
   }
 
   .navbar-item.has-dropdown a.navbar-link figure {
-    margin-right: 0.75rem;
+    @include margin-right(0.75rem);
     display: flex;
     align-items: center;
   }
diff --git a/js/src/components/PictureUpload.vue b/js/src/components/PictureUpload.vue
index 87e763ef4..5929a5e02 100644
--- a/js/src/components/PictureUpload.vue
+++ b/js/src/components/PictureUpload.vue
@@ -51,13 +51,14 @@
 </template>
 
 <style scoped lang="scss">
+@use "@/styles/_mixins" as *;
 .root {
   display: flex;
   align-items: center;
 }
 
 figure.image {
-  margin-right: 30px;
+  @include margin-right(30px);
   max-height: 200px;
   max-width: 200px;
   overflow: hidden;
@@ -99,7 +100,7 @@ figure.image {
       text-overflow: ellipsis;
       white-space: nowrap;
       overflow: hidden;
-      margin-right: 5px;
+      @include margin-right(5px);
     }
   }
 }
diff --git a/js/src/components/Post/PostListItem.vue b/js/src/components/Post/PostListItem.vue
index c9d37ff1c..d8d83825d 100644
--- a/js/src/components/Post/PostListItem.vue
+++ b/js/src/components/Post/PostListItem.vue
@@ -71,6 +71,7 @@ export default class PostListItem extends Vue {
 }
 </script>
 <style lang="scss" scoped>
+@use "@/styles/_mixins" as *;
 @import "~bulma/sass/utilities/mixins.sass";
 
 .post-minimalist-card-wrapper {
@@ -100,7 +101,7 @@ export default class PostListItem extends Vue {
   }
   ::v-deep .icon {
     vertical-align: middle;
-    margin-right: 5px;
+    @include margin-right(5px);
   }
 
   ::v-deep .tags {
diff --git a/js/src/components/Resource/ResourceItem.vue b/js/src/components/Resource/ResourceItem.vue
index 6099a10ad..3f225c892 100644
--- a/js/src/components/Resource/ResourceItem.vue
+++ b/js/src/components/Resource/ResourceItem.vue
@@ -82,6 +82,7 @@ export default class ResourceItem extends Vue {
 }
 </script>
 <style lang="scss" scoped>
+@use "@/styles/_mixins" as *;
 .resource-wrapper {
   display: flex;
   flex: 1;
@@ -137,7 +138,7 @@ a {
       display: inline-block;
       width: 16px;
       height: 16px;
-      margin-right: 6px;
+      @include margin-right(6px);
       vertical-align: middle;
     }
 
diff --git a/js/src/components/Todo/CompactTodo.vue b/js/src/components/Todo/CompactTodo.vue
index 3f4ebf541..4d745c938 100644
--- a/js/src/components/Todo/CompactTodo.vue
+++ b/js/src/components/Todo/CompactTodo.vue
@@ -66,7 +66,8 @@ export default class Todo extends Vue {
 }
 </script>
 <style lang="scss" scoped>
+@use "@/styles/_mixins" as *;
 span.details {
-  margin-left: 1rem;
+  @include margin-left(1rem);
 }
 </style>
diff --git a/js/src/styles/_event-card.scss b/js/src/styles/_event-card.scss
index f657bc47d..4854de21b 100644
--- a/js/src/styles/_event-card.scss
+++ b/js/src/styles/_event-card.scss
@@ -1,9 +1,11 @@
+@use "@/styles/_mixins" as *;
+
 .event-organizer {
   display: flex;
   align-items: center;
 
   .organizer-name {
-    padding-left: 5px;
+    @include padding-left(5px);
     font-weight: 600;
   }
 }
@@ -13,6 +15,6 @@
   align-items: center;
 
   & > span:not(.icon) {
-    padding-left: 5px;
+    @include padding-left(5px);
   }
 }
diff --git a/js/src/styles/_mixins.scss b/js/src/styles/_mixins.scss
new file mode 100644
index 000000000..040d3ae82
--- /dev/null
+++ b/js/src/styles/_mixins.scss
@@ -0,0 +1,55 @@
+@mixin margin($block-start, $inline-end, $block-end, $inline-start) {
+  @include margin-left($inline-start);
+  @include margin-right($inline-end);
+
+  margin-top: $block-start;
+  margin-bottom: $block-end;
+}
+
+@mixin padding($block-start, $inline-end, $block-end, $inline-start) {
+  @include padding-left($inline-start);
+  @include padding-right($inline-end);
+
+  padding-top: $block-start;
+  padding-bottom: $block-end;
+}
+
+@mixin margin-left($value) {
+  @supports (margin-inline-start: $value) {
+    margin-inline-start: $value;
+  }
+
+  @supports not (margin-inline-start: $value) {
+    margin-left: $value;
+  }
+}
+
+@mixin margin-right($value) {
+  @supports (margin-inline-end: $value) {
+    margin-inline-end: $value;
+  }
+
+  @supports not (margin-inline-end: $value) {
+    margin-right: $value;
+  }
+}
+
+@mixin padding-left($value) {
+  @supports (padding-inline-start: $value) {
+    padding-inline-start: $value;
+  }
+
+  @supports not (padding-inline-start: $value) {
+    padding-left: $value;
+  }
+}
+
+@mixin padding-right($value) {
+  @supports (padding-inline-end: $value) {
+    padding-inline-end: $value;
+  }
+
+  @supports not (padding-inline-end: $value) {
+    padding-right: $value;
+  }
+}
diff --git a/js/src/views/Account/children/EditIdentity.vue b/js/src/views/Account/children/EditIdentity.vue
index 5d4e5f5e7..5395cdb49 100644
--- a/js/src/views/Account/children/EditIdentity.vue
+++ b/js/src/views/Account/children/EditIdentity.vue
@@ -215,7 +215,7 @@ h1 {
 }
 
 ::v-deep .buttons > *:not(:last-child) .button {
-  margin-right: 0.5rem;
+  @include margin-right(0.5rem);
 }
 </style>
 
diff --git a/js/src/views/Discussions/Discussion.vue b/js/src/views/Discussions/Discussion.vue
index a016318d1..20fe5f6a9 100644
--- a/js/src/views/Discussions/Discussion.vue
+++ b/js/src/views/Discussions/Discussion.vue
@@ -496,6 +496,7 @@ export default class Discussion extends mixins(GroupMixin) {
 }
 </script>
 <style lang="scss" scoped>
+@use "@/styles/_mixins" as *;
 div.container.section {
   background: white;
   padding: 1rem 5% 4rem;
@@ -507,7 +508,7 @@ div.container.section {
 
     h1.title {
       margin-bottom: 0;
-      margin-right: 10px;
+      @include margin-right(10px);
     }
 
     form.title-edit {
diff --git a/js/src/views/Event/Edit.vue b/js/src/views/Event/Edit.vue
index 341d5212c..611e1f6da 100644
--- a/js/src/views/Event/Edit.vue
+++ b/js/src/views/Event/Edit.vue
@@ -459,6 +459,7 @@
 </template>
 
 <style lang="scss" scoped>
+@use "@/styles/_mixins" as *;
 main section > .container {
   background: $white;
 
@@ -537,7 +538,7 @@ section {
 
       .navbar-end {
         justify-content: flex-end;
-        margin-left: auto;
+        @include margin-left(auto);
       }
     }
   }
diff --git a/js/src/views/Event/Event.vue b/js/src/views/Event/Event.vue
index 3756830e3..a81c7bb44 100755
--- a/js/src/views/Event/Event.vue
+++ b/js/src/views/Event/Event.vue
@@ -1151,6 +1151,7 @@ export default class Event extends EventMixin {
 }
 </script>
 <style lang="scss" scoped>
+@use "@/styles/_mixins" as *;
 .section {
   padding: 1rem 2rem 4rem;
 }
@@ -1192,7 +1193,7 @@ div.sidebar {
 
       span {
         line-height: 2.7rem;
-        padding-right: 6px;
+        @include padding-right(6px);
       }
     }
   }
@@ -1239,7 +1240,7 @@ div.sidebar {
     min-width: 20rem;
     flex: 1;
     @media all and (min-width: 672px) {
-      padding-left: 1rem;
+      @include padding-left(1rem);
     }
 
     .sticky {
@@ -1281,7 +1282,7 @@ div.sidebar {
     ::v-deep blockquote {
       border-left: 0.2em solid #333;
       display: block;
-      padding-left: 1em;
+      @include padding-left(1rem);
     }
 
     ::v-deep p {
@@ -1327,7 +1328,7 @@ a.dropdown-item,
 button.dropdown-item {
   white-space: nowrap;
   width: 100%;
-  padding-right: 1rem;
+  @include padding-right(1rem);
   text-align: right;
 }
 
@@ -1362,7 +1363,7 @@ a.participations-link {
     align-items: flex-end;
     align-self: flex-start;
     margin-bottom: 7px;
-    margin-left: 0rem;
+    @include margin-left(0);
   }
 }
 .title {
diff --git a/js/src/views/Group/Group.vue b/js/src/views/Group/Group.vue
index 8e5033df3..8ddd264e2 100644
--- a/js/src/views/Group/Group.vue
+++ b/js/src/views/Group/Group.vue
@@ -1057,6 +1057,7 @@ export default class Group extends mixins(GroupMixin) {
 }
 </script>
 <style lang="scss" scoped>
+@use "@/styles/_mixins" as *;
 @import "~bulma/sass/utilities/mixins.sass";
 div.container {
   margin-bottom: 3rem;
@@ -1074,7 +1075,7 @@ div.container {
 
   .header .breadcrumb {
     margin-bottom: 0.5rem;
-    margin-left: 0.5rem;
+    @include margin-left(0.5rem);
   }
 
   .block-container {
@@ -1132,7 +1133,7 @@ div.container {
         align-content: space-between;
 
         & > span {
-          margin-right: 0.5rem;
+          @include margin-right(0.5rem);
         }
       }
 
@@ -1165,10 +1166,10 @@ div.container {
         margin: 0 0.5rem;
 
         &:first-child {
-          margin-left: 0;
+          @include margin-left(0);
         }
         &:last-child {
-          margin-right: 0;
+          @include margin-right(0);
         }
       }
 
@@ -1259,7 +1260,7 @@ div.container {
           justify-content: center;
 
           ::v-deep .b-tooltip {
-            padding-right: 0.5em;
+            @include padding-right(0.5em);
           }
         }
 
@@ -1274,7 +1275,7 @@ div.container {
           }
 
           figure:not(:first-child) {
-            margin-left: -10px;
+            @include margin-left(-10px);
           }
         }
       }
@@ -1291,9 +1292,9 @@ div.container {
     .group-metadata {
       min-width: 20rem;
       flex: 1;
-      padding-left: 1rem;
+      @include padding-left(1rem);
       @include mobile {
-        padding-left: 0;
+        @include padding-left(0);
       }
 
       .sticky {
@@ -1330,7 +1331,7 @@ div.container {
   .menu-dropdown {
     ::v-deep .dropdown-item,
     ::v-deep .has-link a {
-      padding-right: 1rem;
+      @include padding-right(1rem);
     }
   }
 
diff --git a/js/src/views/Home.vue b/js/src/views/Home.vue
index f0df7c5c5..751f94b7e 100644
--- a/js/src/views/Home.vue
+++ b/js/src/views/Home.vue
@@ -609,6 +609,7 @@ export default class Home extends Vue {
 </script>
 
 <style lang="scss" scoped>
+@use "@/styles/_mixins" as *;
 @import "~bulma/sass/utilities/mixins.sass";
 
 main > div > .container {
@@ -623,7 +624,7 @@ main > div > .container {
 
 .events-recent {
   & > h3 {
-    padding-left: 0.75rem;
+    @include padding-left(0.75rem);
   }
 
   .columns {
@@ -637,7 +638,7 @@ main > div > .container {
   margin: 0.5rem auto 1rem;
 
   h3.subtitle {
-    margin-left: 7px;
+    @include margin-left(7px);
   }
 }
 
diff --git a/js/src/views/Posts/Edit.vue b/js/src/views/Posts/Edit.vue
index abaebef1a..7d1a3182b 100644
--- a/js/src/views/Posts/Edit.vue
+++ b/js/src/views/Posts/Edit.vue
@@ -368,6 +368,7 @@ export default class EditPost extends mixins(GroupMixin, PostMixin) {
 }
 </script>
 <style lang="scss" scoped>
+@use "@/styles/_mixins" as *;
 .container.section {
   background: $white;
 }
@@ -388,7 +389,7 @@ form {
 
       .navbar-end {
         justify-content: flex-end;
-        margin-left: auto;
+        @include margin-left(auto);
       }
     }
   }
diff --git a/js/src/views/Posts/Post.vue b/js/src/views/Posts/Post.vue
index fe0b4b604..7721607d9 100644
--- a/js/src/views/Posts/Post.vue
+++ b/js/src/views/Posts/Post.vue
@@ -368,6 +368,7 @@ export default class Post extends mixins(GroupMixin, PostMixin) {
 }
 </script>
 <style lang="scss" scoped>
+@use "@/styles/_mixins" as *;
 article.post {
   background: $white !important;
   header {
@@ -417,7 +418,7 @@ article.post {
             flex-direction: column;
 
             *:not(:first-child) {
-              padding-left: 5px;
+              @include padding-left(5px);
             }
           }
         }
@@ -478,7 +479,7 @@ article.post {
   button.dropdown-item {
     white-space: nowrap;
     width: 100%;
-    padding-right: 1rem;
+    @include padding-right(1rem);
     text-align: right;
   }
 }
diff --git a/js/src/views/Resources/ResourceFolder.vue b/js/src/views/Resources/ResourceFolder.vue
index e8a6a90b9..248a7ff7b 100644
--- a/js/src/views/Resources/ResourceFolder.vue
+++ b/js/src/views/Resources/ResourceFolder.vue
@@ -754,6 +754,8 @@ export default class Resources extends Mixins(ResourceMixin) {
 }
 </script>
 <style lang="scss" scoped>
+@use "@/styles/_mixins" as *;
+
 .container.section {
   background: $white;
 
@@ -766,7 +768,7 @@ nav.breadcrumb ul {
   align-items: center;
 
   li:last-child .dropdown {
-    margin-left: 5px;
+    @include margin-left(5px);
 
     a {
       justify-content: left;
@@ -785,14 +787,14 @@ nav.breadcrumb ul {
     align-items: center;
 
     ::v-deep .b-checkbox.checkbox {
-      margin-left: 10px;
+      @include margin-left(10px);
     }
 
     .actions {
-      margin-right: 5px;
+      @include margin-right(5px);
 
       & > * {
-        margin-left: 5px;
+        @include margin-left(5px);
       }
     }
   }
@@ -810,11 +812,11 @@ nav.breadcrumb ul {
 
   .resource-checkbox {
     align-self: center;
-    padding-left: 10px;
+    @include padding-left(10px);
     opacity: 0.3;
 
     ::v-deep .b-checkbox.checkbox {
-      margin-right: 0.25rem;
+      @include margin-right(0.25rem);
     }
   }
 
diff --git a/js/src/views/Settings/Notifications.vue b/js/src/views/Settings/Notifications.vue
index cf3abb3a5..937919823 100644
--- a/js/src/views/Settings/Notifications.vue
+++ b/js/src/views/Settings/Notifications.vue
@@ -780,6 +780,7 @@ export default class Notifications extends Vue {
 </script>
 
 <style lang="scss" scoped>
+@use "@/styles/_mixins" as *;
 .field {
   &:not(:last-child) {
     margin-bottom: 1.5rem;
@@ -790,11 +791,12 @@ export default class Notifications extends Vue {
     text-decoration: underline;
     text-decoration-color: #fea72b;
     text-decoration-thickness: 2px;
-    margin-left: 5px;
+    @include margin-left(5px);
   }
 }
 
 ::v-deep .buttons > *:not(:last-child) .button {
   margin-right: 0.5rem;
+  @include margin-right(0.5rem);
 }
 </style>