LinearProgress

Renders a horizontal loading bar - the linear counterpart of CircularProgress. Supports indeterminate (looping), determinate (value-driven), and query (reversed loop) variants, plus a buffer mode on top of determinate. All fills use CSS currentColor; the color prop resolves to theme.palette[color].main.

Architecture: the root element is a <span> (display block, thickness tall, full width, overflow: hidden) that establishes the color context. The track, buffer bar, and primary bar are absolutely positioned spans inside it, all painted with currentColor at different opacities - no extra color tokens needed. Value-driven bars translate with transform: translateX(...) so progress updates animate on the compositor.

Examples

Default

<LinearProgress variant="indeterminate" color="primary" />

Determinate

<LinearProgress variant="determinate" color="primary" value={70} />

Buffer

<LinearProgress
  variant="determinate"
  color="primary"
  value={40}
  buffer
  valueBuffer={70}
/>

Query

<LinearProgress variant="query" color="primary" />

Spinning Determinate

25%
50%
75%
<Flex flexDirection="column" gap={3}>
  {([25, 50, 75] as const).map((value) => (
    <Flex key={value} flexDirection="row" gap={2} alignItems="center">
      <Typography variant="caption" color="secondary" width="6rem" flexShrink={0} m={0}>
        {value}%
      </Typography>
      <LinearProgress variant="determinate" value={value} spinning />
    </Flex>
  ))}
</Flex>

Colors

primary
secondary
success
error
info
warning
<Flex flexDirection="column" gap={3}>
  {(['primary', 'secondary', 'success', 'error', 'info', 'warning'] as const).map((color) => (
    <Flex key={color} flexDirection="row" gap={2} alignItems="center">
      <Typography variant="caption" color="secondary" width="6rem" flexShrink={0} m={0}>
        {color}
      </Typography>
      <LinearProgress variant="determinate" value={65} color={color} />
    </Flex>
  ))}
</Flex>

Thickness

2px
4px
8px
12px
<Flex flexDirection="column" gap={3}>
  {([2, 4, 8, 12] as const).map((thickness) => (
    <Flex key={thickness} flexDirection="row" gap={2} alignItems="center">
      <Typography variant="caption" color="secondary" width="6rem" flexShrink={0} m={0}>
        {thickness}px
      </Typography>
      <LinearProgress variant="determinate" value={65} thickness={thickness} />
    </Flex>
  ))}
</Flex>

Easing

linear
ease
ease-in
ease-out
ease-in-out
<Flex flexDirection="column" gap={3}>
  {(['linear', 'ease', 'ease-in', 'ease-out', 'ease-in-out'] as const).map((easing) => (
    <Flex key={easing} flexDirection="row" gap={2} alignItems="center">
      <Typography variant="caption" color="secondary" width="6rem" flexShrink={0} m={0}>
        {easing}
      </Typography>
      <LinearProgress variant="determinate" value={65} spinning easing={easing} />
    </Flex>
  ))}
</Flex>

Rounded

4px
8px
12px
<Flex flexDirection="column" gap={3}>
  {([4, 8, 12] as const).map((thickness) => (
    <Flex key={thickness} flexDirection="row" gap={2} alignItems="center">
      <Typography variant="caption" color="secondary" width="6rem" flexShrink={0} m={0}>
        {thickness}px
      </Typography>
      <LinearProgress variant="determinate" value={65} thickness={thickness} round />
    </Flex>
  ))}
</Flex>

Without Track

with track
without
<Flex flexDirection="column" gap={3}>
  <Flex flexDirection="row" gap={2} alignItems="center">
    <Typography variant="caption" color="secondary" width="6rem" flexShrink={0} m={0}>
      with track
    </Typography>
    <LinearProgress variant="determinate" value={65} />
  </Flex>
  <Flex flexDirection="row" gap={2} alignItems="center">
    <Typography variant="caption" color="secondary" width="6rem" flexShrink={0} m={0}>
      without
    </Typography>
    <LinearProgress variant="determinate" value={65} showTrack={false} />
  </Flex>
</Flex>

Determinate Animated

<AnimatedDeterminate />

Buffer Animated

<AnimatedBuffer />

With Label

Uploading photos...

20%
<ProgressWithLabel />

Custom Value Text

Elevator status: Ground floor

<ElevatorStatus />

Custom Range

3 of 10
120 of 200
<Flex flexDirection="column" gap={3}>
  {(
    [
      { value: 3, min: 0, max: 10, label: '3 of 10' },
      { value: 120, min: 0, max: 200, label: '120 of 200' },
    ] as const
  ).map(({ value, min, max, label }) => (
    <Flex key={label} flexDirection="row" gap={2} alignItems="center">
      <Typography variant="caption" color="secondary" width="6rem" flexShrink={0} m={0}>
        {label}
      </Typography>
      <LinearProgress variant="determinate" value={value} min={min} max={max} />
    </Flex>
  ))}
</Flex>

LinearProgress API reference