Loader component is used to indicate current status in the UI for various scenarios: when submitting forms, loading data, doing time consuming calculations, etc. It is a way to show users what is currently going on.


Loader size directly corresponds to Icon/Image size.



By default loaders are used as inline elements that can appear almost anywhere. They do not obstruct the whole page/screen, but indicate that some part of the screen/page is loading. For example, such loader can appear at the bottom of the feed to indicate that more items will be loaded.


Lifted loader is used when it is supposed to overlay content, for example, for large page sections or full screen views.


Lifted Loader component sometimes has states indicating success and error moments.

Success state is visible, once the loading process ends successfully. Error state is visible, once the loading process ends unsuccessfully.


Loader can technically accept any theme from the defined Vinted Theme set, yet by default primary theme is used. When no theme is passed, $loader-state-loading-color is used. Using loaders without theme can be beneficial when combined with, for example, Button component.



Loader consists of 3 main parts: containing box (view box), stroke (transparent circle with a border/stroke of specified stroke width) and padding. This implies that the size of the loader (circle) is smaller than the containing box, because we have to account for the specified padding.


Loader animation consists of 2 different motions: loader circle rotation and circle stroke fill percentage (alternatively, path trimming). Stroke fill starts at 12 o'clock position.

Both motions start at the same time and the whole animation is keyframed into 3 distinct points: 0% (initial), 50% (middle) and 100% (end/peak).

// Sizes

$loader-sizes: (
  small: (
    size: unit(3),
    padding: unit(0.25),
    thickness: unit(0.5),

  medium: (
    size: unit(4),
    padding: unit(0.25),
    thickness: unit(0.5),

  default: (
    size: unit(6),
    padding: unit(0.5),
    thickness: unit(0.5),

  large: (
    size: unit(8),
    padding: unit(0.5),
    thickness: unit(0.75),

  x-large: (
    size: unit(12),
    padding: unit(1),
    thickness: unit(1),

  xx-large: (
    size: unit(18),
    padding: unit(1.5),
    thickness: unit(1.25),

  xxx-large: (
    size: unit(24),
    padding: unit(2),
    thickness: unit(2),

// Animation

$loader-animation-length:                 2s;
$loader-animation-easing:                 linear;

$loader-animation-stroke-initial:         0.1;  // treat this as percentage of total stroke filled
$loader-animation-stroke-peak:            0.9;

$loader-animation-rotate-initial:         rotation(0deg);
$loader-animation-rotate-middle:          rotation(360deg);
$loader-animation-rotate-end:             rotation(1080deg);

// States

$loader-state-loading-color:              palette(cg9); // when theme is not set
$loader-state-success-color:              palette(cs1);
$loader-state-error-color:                palette(cs3);


name value default
style default / lifted default
size small / medium / default / large / x-large / xx-large / xxx-large default
state default / success / error default
theme Vinted Theme primary