Kuba Suder's blog on Mac & iOS development

I don’t know about you, but I never know which NSButton to pick from the Interface Builder library panel. When you start looking for a button there, this is what you see:

13 different buttons, all described with the same meaningless description:

The NSButton class is a subclass of NSControl that intercepts mouse-down events and sends an action message to a target object when it’s clicked or pressed.

Each of them looks slightly different, but which of these are you supposed to use in what context?

I started looking for some kind of guide. The NSButtonCell documentation is a good starting point, but the problem is that the bezel styles are listed using the NSBezelStyle constants, most of which sound completely different than their counterparts in Interface Builder… The Controls page in the HIG is the best source I’ve found, but even there the buttons are described in an order that makes it pretty hard to see the whole big picture.

So I figured I could prepare a kind of cheat sheet that collects all this information in one place. The list below describes the button styles in the same order as in the Xcode panel, and for each button it includes: the Xcode name, the constant name, screenshots of how it looks on Yosemite (on the left) and on Mavericks (on the right), and some guidelines I found about how it’s supposed to be used, or how it’s actually used by Apple in their apps. (I’ve even checked the system apps with Interface Inspector to see what controls are actually used where.)

It’s quite possible that I got something wrong and this list may contain various errors – if you catch anything, let me know in the comments.

Push Button / NSRoundedBezelStyle (fixed height)

This is the most standard and most common button, used absolutely everywhere. If you don’t have a good reason to use a different one, this is probably what you want. A push button is supposed to only have a text label (no icon), and it’s meant to execute some kind of specific action when pressed.

Here, a smaller version from Safari preferences:

Push buttons are designed for use in the window body only, not in the window-frame areas.

Users expect an immediate action to occur when they click a push button, including the opening of another window or the dismissal of a dialog.

Don’t use a push button to indicate a state, such as on or off. Instead, you can use checkboxes to indicate state (…).

Avoid associating a menu with a push button.

Gradient Button / NSSmallSquareBezelStyle (variable height)

Although it’s created by default as a rather long button with a text label (in a direct contradiction to the recommendation seen in the quotes below…), this style is meant primarily for small, square or almost square action buttons with icons like a plus sign or a cogwheel. You can see them everywhere in the standard Apple apps, often right below lists or grids.

A gradient button performs an instantaneous action related to a view, such as a source list.

Gradient buttons contain images; they don’t contain text.

Because the function of a gradient button is closely tied to the view with which it’s associated, there’s little need to describe its action using a label.

When possible, use system-provided images, such as the Action and the Add images, because their meaning is familiar to users.

Don’t use a segmented control to enable addition or deletion of objects in a source list or split view. If you need to provide a way for users to add and delete objects in a source list or other split view, use a gradient button (described in “Gradient Button”) in the window body.

In some System Preferences panels in Yosemite, Apple does use a segmented control for the +/– buttons though:

Rounded Rect Button / NSRoundRectBezelStyle (fixed height)

This button’s main purpose is in filtering UIs, where the user can build additional conditions to filter search results by specifying the attributes they’re interested in (the best known example is probably the one in Finder).

A bezel style that matches the search buttons in Finder and Mail.

Scope buttons are designed to be used in scope bars and related filter rows only.

Use a round rectangle scope button to allow users to save a set of search criteria and to change or set scoping criteria.

Although the HIG says it should be used only in scope bars, you can also find it in different contexts in Apple’s apps, e.g. as a lightweight push button in popovers:

(In Mavericks, the “Clear” button is a Square button with a custom cell class.)

Round Textured Button / NSTexturedRoundedBezelStyle (fixed height)

Although it looks like it could be used anywhere in the window body, this button is actually designed to be used in toolbars. That’s why it’s one of the button types that have went through the most visible change in Yosemite – in Mavericks and before, controls in the window toolbar (segmented controls, normal and popup buttons) had a darker, bordered and gradiented style, and in Yosemite they’re white, flat and almost borderless. (It’s kind of ironic that the two buttons named “textured” have now the flattest look in the whole list…)

A textured (metal) bezel style similar in appearance to the Finder’s action (gear) button.

NSTexturedRoundedBezelStyle style of NSButton is designed for use in the window frame.

Textured Button / NSTexturedSquareBezelStyle (variable height)

This is one of the most mysterious button styles – I couldn’t find any information about it apart from the single quote below. It looks almost indistinguishable from the Round Textured one, and it seems to have a similar purpose, so it’s hard to tell which of the buttons in Apple’s apps use the rounded style and which use the square style. Most of the apps I’ve checked used either Round Textured style, or a segmented control; the only place I found the Textured Square one was the bottom window bar in apps like Console, so maybe that’s where it’s meant to be used.

A bezel style appropriate for use with textured (metal) windows.

Recessed Button / NSRecessedBezelStyle (fixed height)

I’ve mistakenly used it as a push button in a popover recently, but it seems this button is designed to be used as a toggle button only. It’s meant to be used in scope selector bars, where you have a line of these and only one of them is selected at a time (like a radio button), and clicking one of them changes the filtering conditions or chooses a different section of the content.

Unlike most of the other button types, a recessed button has a borderless state, which is used when another button in the row is selected.

A bezel style that matches the recessed buttons in Mail, Finder and Safari.

Scope buttons are designed to be used in scope bars and related filter rows only.

Use a recessed scope button to display types or groups of objects or locations that users select to narrow the focus of a search or other operation.

Disclosure Triangle / NSDisclosureBezelStyle (fixed size)

This one’s pretty self-explanatory – use it to show/hide some additional information or a section that users don’t need to see by default.

A disclosure triangle displays (or discloses) information or functionality associated with the primary information in a window.

Use a disclosure triangle when you want to provide a simple default view of something but need to allow users to view more details or perform additional actions at specific times. In general, you can use a disclosure triangle in the following two ways:

To reveal more information in dialogs that have a minimal state and an expanded state. For example, you might want to use a disclosure triangle to hide explanatory information about a choice that most users aren’t interested in seeing.

Supply a label for a disclosure triangle in a dialog. The label should indicate what is disclosed or hidden and it should change, depending on the position of the disclosure triangle. For example, when the disclosure triangle is closed the label might be “Show advanced settings;” when the disclosure triangle is open the label can change to “Hide advanced settings.”

Don’t use a disclosure triangle to display additional choices associated with a specific control. If you need to do this, use a disclosure button instead (…).

Square Button / NSShadowlessSquareBezelStyle (variable height)

I couldn’t find much info about this button type. It’s probably in the same group as the Bevel button – not intended to be used anymore. You can however still use this type (or the Bevel type) with the border turned off to create borderless icon buttons – unlike most other button types, these two can be set to any height you want.

These aren’t actually Square buttons, but the HIG shows System Preferences as an example of icon buttons, right above the second quote below:

Similar to NSRegularSquareBezelStyle [aka Bevel Button], but has no shadow so you can abut [wtf?] the cells without overlapping shadows. This style would be used in a tool palette, for example.

To create an icon button in Interface Builder, drag a bevel button or a square button into your window, add your icon, and deselect the Bordered checkbox in the Attributes pane of the inspector. To create one using AppKit programming interfaces, use the setBezelStyle: method of NSButtonCell with NSShadowlessSquareBezelStyle as the argument.

Help Button / NSHelpButtonBezelStyle (fixed size)

This button is supposed to open a help dialog, or otherwise explain the user what is going on in the given dialog. You can often find them in panels of preferences windows.

The Help button opens a window that displays app-specific help.

In dialogs (including preferences windows) and drawers, the Help button can be located in either the lower-left or lower-right corner. In a dialog that includes OK and Cancel buttons (or other buttons used to dismiss the dialog), the Help button should be in the lower-left corner, vertically aligned with the buttons. In a dialog that does not include OK and Cancel buttons, such as a preferences window, the Help button should be in the lower-right corner.

Disclosure Button / NSRoundedDisclosureBezelStyle (fixed size)

Very similar to the Disclosure Triangle, except this one is supposed to be always used together with another control, for which it provides additional info. Think the standard Save dialog: the popup control lets you pick one of the default locations to save the file, and if you aren’t happy with any of those, you click the disclosure button to expand the dialog and let you pick any location in the filesystem.

A bezel style that matches the disclosure style used in the standard Save panel.

A disclosure button expands a dialog or panel to display a wider range of choices related to a specific selection control.

Use a disclosure button when you need to provide additional options that are closely related to a specific list of choices.

Place a disclosure button close to the control to which it’s related. Users need to understand how the expanded choices are related to their current task. For example, the Preview Export As dialog puts a disclosure button close to the Export As text field, so that users understand that the expanded view will help them choose a location for their document.

Don’t use a disclosure button to display additional information or functionality or subordinate items in a list. If you need to display additional information or functionality related to the contents of a window or a section of a window, or if you need a way to reveal subordinate items in a hierarchical list, use a disclosure triangle instead.

Round Button / NSCircularBezelStyle (fixed size)

I couldn’t recognize the button at first, and for a good reason – it appears this is a remnant from the older OSXes and it’s not supposed to be used anymore. Nothing to see here, move along.

A round button with room for a small icon or a single character. This style has both regular and small variants, but the large variant is available only in gray at this time.

A round button initiates an immediate action.

Round buttons are not recommended for use in apps that run in OS X v10.7 and later. You should consider an alternative, such as a gradient button (…).

Round buttons, like bevel buttons, are seldom used in modern Mac apps. You might want to use a gradient button that contains a system-provided (or custom) image as an alternative.

Bevel Button / NSRegularSquareBezelStyle (variable height)

I’ve been tempted to use this button from time to time, but it turns out this one’s also sort of deprecated. I guess it makes sense, it looks pretty ugly anyway with the small font…

This button has also two other variants, which only appear in the documentation, but not in the Interface Builder: NSThickSquareBezelStyle and NSThickerSquareBezelStyle. As far as I can tell, they look identical as the bevel button in the last two OSX versions.

A rectangular button with a 2 point border, designed for icons.

A bevel button is a multipurpose button designed for use in the window-body area.

They can display text, icons, or other images.

Note: Bevel buttons are not recommended for use in apps that run in OS X v10.7 and later. You should consider alternatives, such as gradient buttons and segmented controls (…).

However, I’ve found some examples of this button style in Apple’s apps on Yosemite – they appear in some apps with recently redesigned UIs like Contacts. So maybe it’s OK to use the Bevel style after all, as long as you change the default font, or use it with an icon label. (And take into account that it looks uglier on pre-Yosemite systems…)

The same apps in Mavericks either use buttons with custom classes (Contacts), or simply have the whole button bezel prerendered on an image (Reminders). Alternatively, you could check the OS version in the code and change the button style to e.g. Round Textured in awakeFromNib if it’s less than 10.10.

Inline Button / NSInlineBezelStyle (fixed height, 10.7+)

The newest of the button styles, it looks similar to the Recessed button, except it’s supposed to be used either as a push button, or as an unclickable indicator inside lists.

The inline bezel style contains a solid round-rect border background. It can be used to create an “unread” indicator in an outline view, or another inline button in a tableview, such as a stop progress button in a download panel. Use text for an unread indicator, and a template image for other buttons.

Bonus: Segmented controls

While inspecting some of the built-in apps, I’ve noticed that some of the buttons I’ve looked at aren’t actually buttons – they’re segmented controls with a single segment, with trackingMode set to NSSegmentSwitchTrackingMomentary (“Select None”). The HIG doesn’t mention that you can use segmented controls as buttons this way, but neither does it say that you can’t do that…

There’s also no information about what the specific styles should be used for, so I’m just going to list all available styles with screenshots (only in the single-segment variant):

You've skipped over the curliest of the bunch: the checkbox! And ditto @aure — I still get tripped up subclassing these guys.

Stefan Hong

Wednesday, 16 September 2015, 08:24

Thank you so much! I finally know the intended use of these button types.

Quinn Taylor

Friday, 13 May 2016, 04:50

Hopefully you noticed the improvement in Xcode 7. I had filed a bug about a month before you posted this, and integrated button content and useful descriptions in the object library. Thanks for the detailed write up!