Developer mode
Opens components on the React tab by default.
Your bookmarks

Progressive disclosure

Simplify your designs while keeping all information and options available.

Users come to your designs with competing desires. They want to be able to do a lot (features) but they don’t want to spend time learning how to do it (simplicity). How can you give them everything without overwhelming them?

The answer is progressive disclosure. By following this principle, you show users only what they need at a given time to make a decision and keep everything else a tap away. This means deciding what the most important options are in a given flow and making it clear to users how they can get to other options.

Read more about progressive disclosure, see some examples of how we implement it in Orbit, and explore what components you can use in your own designs.

What progressive disclosure means for you

Progressive disclosure is a way to manage the vast amount of information you have available. If you try to present all possible choices to users at once, it will be difficult for them to choose what is important and what isn’t. This leads to them getting overwhelmed by information (known as information overload) and increases the chance that they won’t do anything.

Three options with buttons: 1. everything primary, 2. one primary and the rest secondary, 3. everything secondary.
On the left, we can see that when everything is important, nothing is. To fix this, either highlight the one most important action (the middle option) or make them all less distinct (the option on the right).

To help users through this, you’ll want to simplify your designs to highlight what’s important. It’s important to remember to make it clear that the secondary choices are still available and how users can get to them if they want.

The idea of user desire is important because you don’t want users to think they can’t do something that they actually can. You want to make sure they don’t leave in search of another solution to do something they can achieve with your design.

How to choose what’s most important

When you’re thinking about what should be displayed by default, you want to consider several questions. The answers should help you decide what should be displayed by default and what can be progressively disclosed over time.

  • What is the user’s primary goal at this moment?
    • Here, it’s not just about the overall goal (such as booking a flight within a budget), but the goal on a given screen (such as choosing a date).
  • Is there any information that users would need to know some of the time, but not always?
    • Are there any advanced options that fit certain scenarios, but aren’t likely to be used by everyone?
  • If all of the information were displayed and users could choose to hide some of it, what would many of them choose?
    • User testing could come in handy to determine what people find unnecessary.
  • Is any of the information additional explanation of something already present?
    • If something is present, it’s a good candidate for an interaction that can show more details.

When you’ve come up with answers to such questions, choose only the important information and display it clearly. Then organize everything else so that users can clearly see how to access it if they want.

Examples

There are many places in Orbit where we have progressive disclosure baked into the components. We’ve designed them so that they progressively disclose information without you having to set it up. 

Slider

You can see one example if you move the handler in the slider below.

import Slider from "@kiwicom/orbit-components/lib/Slider";
<Slider
    defaultValue={12}
    histogramData={[
      11,
      25,
      37,
      5,
      21,
      27,
      24,
      33,
      16,
      21,
      22,
      2,
      11,
      25,
      37,
      5,
      21,
      27,
      24,
      33,
      16,
      21,
      22,
      2
    ]}
    label="Depart from Prague"
    maxValue={24}
    minValue={1}
    valueDescription="01:00 AM–11:59 PM"
  />

At first sight, you can see the range that is being selected, but it is only after interacting with the slider that you’ll see more details in the histogram. 

Error forms

We also have more complex patterns that follow this principle, such as how we deal with errors in forms.

Nomad

You can see another example of this practice in the process of adding destinations in Nomad, a Kiwi.com tool for exploring the world with a flexible itinerary. When you first try to add a place, all you see is a list of potential destinations.

Your choices are limited to the primary option: the place. Once you have chosen a place, it’s added to your list along with a standard length to stay. This length is highlighted in the UI as a place where there are additional options.

If you select this, you’ll find additional options for the length of stay.

Even here, there is only one primary action: a slider to choose a length of stay.

People who have more specific desires (who might not be the primary audience for Nomad, but who might also use it) can use a secondary button to open even more advanced options for choosing dates. The path to get additional choices is clear, but each step along the way presents only a single main action so users know what to focus on.

How to use with Orbit

Orbit gives you several options for implementing this principle in addition to the components where it’s already in place, like the slider example above

Truncate

Truncate components make long text fit within a given space. The text is present on the page, but hidden by default. This lets you show various amounts of text based on user actions or at various sizes, as in the example below.

import Truncate from "@kiwicom/orbit-components/lib/Truncate";
import Stack from "@kiwicom/orbit-components/lib/Stack";
<Stack direction="row">
  <Truncate>
    <Text>
      Switch between viewports to see more text. It is a really long
      text that will not appear in full in any of the viewports that
      we offer. It will be hidden behind truncation so that it is
      present in the code but not shown.
    </Text>
  </Truncate>
</Stack>

Collapse

Collapse components hide long information so that it’s not cluttering up the screen. They’re great for hiding things like options that have reasonable defaults that most people wouldn’t change, but some people might want to. This is especially true where there are multiple groups of such options.

The example below could be used to hide options for filtering a search where most people would want to get to their destination in any way possible, but some people only want certain options. 

import Checkbox from "@kiwicom/orbit-components/lib/Checkbox";
import ChoiceGroup from "@kiwicom/orbit-components/lib/ChoiceGroup";
import Collapse from "@kiwicom/orbit-components/lib/Collapse";
<Collapse
  label="Transport"
>
  <ChoiceGroup
    filter
  >
    <Checkbox
      checked
      label="Flight"
      value="one"
    />
    <Checkbox
      checked
      label="Bus"
      value="two"
    />
    <Checkbox
      checked
      label="Train"
      value="three"
    />
  </ChoiceGroup>
</Collapse>

Popover

Popovers help reduce clutter in your designs by keeping small bits of information hidden behind an interaction. They work well for units of slightly complex options (if it gets to be very complicated, consider a modal to structure it all).

The example below shows a button displaying the current number of selected passengers. When it’s clicked, additional options for adding or removing passengers can be seen. This is an action that wouldn’t happen repeatedly during a flow, so it’s best to hide it when it’s not being used.

import Button from "@kiwicom/orbit-components/lib/Button";
import ChevronDown from "@kiwicom/orbit-components/lib/icons/ChevronDown";
import Passengers from "@kiwicom/orbit-components/lib/icons/Passengers";
import Popover from "@kiwicom/orbit-components/lib/Popover";
import Stack from "@kiwicom/orbit-components/lib/Stack";
import Stepper from "@kiwicom/orbit-components/lib/Stepper";
import Text from "@kiwicom/orbit-components/lib/Text";
<Popover
  content={
    <Stack>
      <Stack align="center">
        <Stack spacing="none">
          <Text>Adult</Text>
          <Text type="secondary">11+</Text>
        </Stack>
        <Stepper defaultValue={1} minValue={1} />
      </Stack>
      <Stack align="center">
        <Stack spacing="none">
          <Text>Child</Text>
          <Text type="secondary">2-11</Text>
        </Stack>
        <Stepper minValue={0} />
      </Stack>
    </Stack>
  }
>
  <Button iconLeft={<Passengers />} iconRight={<ChevronDown />} type="secondary">
    1
  </Button>
</Popover>

Tooltip

Tooltips highlight text to show that there is additional context available behind the text. They are a basic way of keeping information present but hidden.

You can see an example in the pricing table below. The features are presented simply for comparison, but each has a tooltip for explaining additional details. This can separate more complex information, like lists.

import Button from "@kiwicom/orbit-components/lib/Button";
import Badge from "@kiwicom/orbit-components/lib/Badge";
import Check from "@kiwicom/orbit-components/lib/icons/Check";
import Close from "@kiwicom/orbit-components/lib/icons/Close";
import FeatureIcon from "@kiwicom/orbit-components/lib/FeatureIcon";
import List, { ListItem } from "@kiwicom/orbit-components/lib/List";
import PricingTable, { PricingTableItem } from "@kiwicom/orbit-components/lib/PricingTable";
import Tooltip from "@kiwicom/orbit-components/lib/Tooltip";
import Text from "@kiwicom/orbit-components/lib/Text";
<PricingTable>
  <PricingTableItem
    action={<Button fullWidth>Continue with Basic</Button>}
    featureIcon={<FeatureIcon name="TicketSaver" />}
    mobileDescription="Basic tickets include:"
    name="Basic"
    price="$349"
  >
    <List type="separated">
      <ListItem
        icon={<Check color="success" size="small"/>}
        label="Kiwi.com services"
      >
        <Tooltip
          content="Extra info about basic services"
          stopPropagation
        >
          <Text>
            Basic
          </Text>
        </Tooltip>
      </ListItem>
      <ListItem
        icon={<Close color="error" size="small"/>}
        label="Rebooking"
      >
        <Tooltip
          content="Extra info about rebooking"
          stopPropagation
        >
          <Text>
            New ticket
          </Text>
        </Tooltip>
      </ListItem>
      <ListItem
        icon={<Close color="error" size="small"/>}
        label="Cancelation"
      >
        <Text>
          $10 refund
        </Text>
      </ListItem>
    </List>
  </PricingTableItem>
  <PricingTableItem
    action={<Button fullWidth>Continue with Premium</Button>}
    badge={<Badge type="info">Recommended</Badge>}
    featureIcon={<FeatureIcon name="TicketFlexi" />}
    mobileDescription="Premium tickets include:"
    name="Premium"
    price="$595"
  >
    <List type="separated">
      <ListItem
        icon={<Check color="success" size="small"/>}
        label="Kiwi.com services"
      >
        <Tooltip
          content="Extra info about basic services"
          stopPropagation
        >
          <Text>
            Extended
          </Text>
        </Tooltip>
      </ListItem>
      <ListItem
        icon={<Check color="success" size="small"/>}
        label="Rebooking"
      >
        <Tooltip
          content="Extra info about rebooking"
          stopPropagation
        >
          <Text>
            Pay the difference
          </Text>
        </Tooltip>
      </ListItem>
      <ListItem
        icon={<Check color="success" size="small"/>}
        label="Cancelation"
      >
        <Text>
          90% refund
        </Text>
      </ListItem>
    </List>
  </PricingTableItem>
</PricingTable>

CardSection

Cards are great at grouping together static content, like long complex information. When that information gets longer or has chunks that are similar, you can hide details using expandable card sections. That way the structure of the information remains clear, but users aren’t overwhelmed by details.

The example below shows how you could group passenger details with a card. The most important information can be shown as the section title, so people can see the names at a glance, and then anything else is just a quick expand away.

import Card, { CardSection } from "@kiwicom/orbit-components/lib/Card";
import GenderMan from "@kiwicom/orbit-components/lib/icons/GenderMan";
import GenderWoman from "@kiwicom/orbit-components/lib/icons/GenderWoman";
import Text from "@kiwicom/orbit-components/lib/Text";
<Card
  title="Passengers on this segment"
>
  <CardSection icon={<GenderWoman />} expandable title="Andrea Garcia">
    <Text type="secondary">13 May 1990</Text>
    <Text type="secondary">agarcia@example.com</Text>
    <Text type="secondary">001245745 5657</Text>
  </CardSection>
  <CardSection icon={<GenderMan />} expandable title="Walter Watkins">
    <Text type="secondary">20 January 1992</Text>
    <Text type="secondary">walterwatkins@example.com</Text>
    <Text type="secondary">001245745 5758</Text>
  </CardSection>
</Card>