diff --git a/include/utils/math.hpp b/include/utils/math.hpp
index 93b28474..e6186e54 100644
--- a/include/utils/math.hpp
+++ b/include/utils/math.hpp
@@ -56,7 +56,18 @@ namespace math_util {
   }
 
   /**
-   * Get value for percentage of `max_value`
+   * Get value for signed percentage of `max_value` (cap between -max_value and max_value)
+   */
+  template <typename ValueType, typename ReturnType = int>
+  ReturnType signed_percentage_to_value(ValueType signed_percentage, ValueType max_value) {
+    if (std::is_integral<ReturnType>())
+      return cap<ReturnType>(signed_percentage * max_value / 100.0f + 0.5f, -max_value, max_value);
+    else
+      return cap<ReturnType>(signed_percentage * max_value / 100.0f, -max_value, max_value);
+  }
+
+  /**
+   * Get value for percentage of `max_value` (cap between 0 and max_value)
    */
   template <typename ValueType, typename ReturnType = int>
   ReturnType percentage_to_value(ValueType percentage, ValueType max_value) {
diff --git a/src/x11/tray_manager.cpp b/src/x11/tray_manager.cpp
index 2932868f..da2793b4 100644
--- a/src/x11/tray_manager.cpp
+++ b/src/x11/tray_manager.cpp
@@ -150,17 +150,17 @@ void tray_manager::setup(const bar_settings& bar_opts) {
 
   if (offset_x != 0 && offset_x_def.find('%') != string::npos) {
     if (m_opts.detached) {
-      offset_x = math_util::percentage_to_value<int>(offset_x, bar_opts.monitor->w);
+      offset_x = math_util::signed_percentage_to_value<int>(offset_x, bar_opts.monitor->w);
     } else {
-      offset_x = math_util::percentage_to_value<int>(offset_x, inner_area.width);
+      offset_x = math_util::signed_percentage_to_value<int>(offset_x, inner_area.width);
     }
   }
 
   if (offset_y != 0 && offset_y_def.find('%') != string::npos) {
     if (m_opts.detached) {
-      offset_y = math_util::percentage_to_value<int>(offset_y, bar_opts.monitor->h);
+      offset_y = math_util::signed_percentage_to_value<int>(offset_y, bar_opts.monitor->h);
     } else {
-      offset_y = math_util::percentage_to_value<int>(offset_y, inner_area.height);
+      offset_y = math_util::signed_percentage_to_value<int>(offset_y, inner_area.height);
     }
   }