Page MenuHomePhabricator

Investigate how to ensure proper spacing between icons and labels in Button
Closed, ResolvedPublic


In order to use the quiet button with icon in the Mismatch Finder, we need to investigate how to ensure that the spacing between icons and labels in buttons is right.

Our current approach to displaying icons within our different button variants involves inserting them in the existing button slot, to the left and/or the right of the text label. We should make sure that this approach still allows us to apply a proper spacing between the icon and the button label (as defined by the button design specs).


  • As an approach, we may decide to add a prefix and suffix slots to the button that will only accept Icon children.
  • Another approach could be to add a "left" or "right" prop to the Icon that then adds the expected padding to that icon, like in vuetify:

Event Timeline

Sarai-WMDE updated the task description. (Show Details)
Sarai-WMDE updated the task description. (Show Details)
Sarai-WMDE renamed this task from Investigate how to ensure proper spacing between button's icon and label to Investigate how to ensure proper spacing between buttons' icons and labels.Dec 16 2020, 6:06 PM
Sarai-WMDE renamed this task from Investigate how to ensure proper spacing between buttons' icons and labels to Investigate how to ensure proper spacing between icons and labels in Button.Jan 11 2021, 10:19 AM

Prio Notes:

  • Required by an ongoing hike
  • Affects implementers of the design system

Investigation Report

Three approaches can be considered in order to achieve a proper spacing within the context of a button: CSS-Only approach, Button - context approach (slots), Icon - context approach (prop).

CSS Only Approach

In this approach, we style the Icon as a descendant of Button within the Button's CSS, to add margins to Icon and ensure proper spacing.

Usage Example

<Button type="danger">
    <Icon type="trash" /> Delete
  • Changes are done only within the required context
  • No need to change any component's API in order to enable this
  • Quick and easy to apply
  • There isn't an "intelligent" way to decide which margins to add (i.e. we cannot tell if the icon is before the text, after it or in the middle of it.), In every scenario the same amount of margins are to be added.
  • Implementers will have to override styling in case they are not interested in this margin

While the simplest method to apply and implement, it might not fit our case, as we need to be sensitive to where the icon is placed. Although the cons can be mitigated with the introduction of Icon placement props to the Button element, this is not desirable as it would invalidate almost all pro points.

Button Context (slots) approach

This approach entails adding two slot points into the Button (and possibly ToggleButton) component, to enable implementers to specify particular HTML to go before, and after the button label. With slots, we may also ensure that only Icon components are added to these slots.

Usage Example

<Button type="danger">
   <template v:slot=prefix>
       <Icon type="trash" />
  • Does not interfere with any Icons implementers want to include as part of the label
  • Allows us to apply any styles for each of the scenarios of Icon inclusion (before or after label)
  • Spacing is limited to the context of the button
  • Changing the slot structure of the Button component is not a quick or simple task
  • Does not cover cases where the Icon is in the middle of the label (If desired)
  • Cumbersome syntax

This method ensures that any decision we make regarding spacing remains in the context of the button component, as was required by this task. While the implementation effort might be higher here, it seems to me to be the most favorable way forward considering the balance between implementation freedom and design system control.

Icon Context (props) approach

This approach entails adding binary style properties to the Icon component to determine whether the component needs extra padding in one or more of its sides.

Usage Example

<Button type="danger">
    <Icon type="trash" right /> Delete
  • Relatively simple to implement
  • Maintains a high level of freedom of implementation
  • Arbitrary padding sizes might not fit all scenarios
  • Violates separation of concerns between semantics and presentation

This method seems much cleaner and simpler to implement than the one mentioned above. However, it introduces a context insensitive spacing that must fit to all given scenarios.


While the Icon context approach affords the most simplicity both in implementation and in usage, it disregards (as it should) the context of the Icon's implementation and thus the spacing might be arbitrary in any other scenario besides the button implementation. In opposition, the Button context approach is a bit more complex in terms of both implementation and usage, but it affords the most transparency to the intent of this spacing, as well as ensures that it is scoped only to the context where it is meant to be applied.

Sarai-WMDE raised the priority of this task from Low to Needs Triage.Feb 10 2021, 6:27 PM

Thanks @ItamarWMDE for the investigation! I agree that the slots approach makes the most sense .

Here's an implementation

Sarai-WMDE claimed this task.
Sarai-WMDE moved this task from Needs review to Done on the Wikidata Design System board.