# How to Add ANSI Colors to Table Cells Using Outfancy

> Learn how to add ANSI colors to table cells with Outfancy. Embed color codes directly into your table data for vibrant, informative output. See how simple it is!

- Repository: [Carlos A. Planchón/outfancy](https://github.com/carlosplanchon/outfancy)
- Tags: how-to-guide
- Published: 2026-02-26

---

**Outfancy preserves ANSI escape sequences in cell values and only strips them internally when calculating column widths via `widgets.printed_length`, allowing you to embed color codes directly from `outfancy.colors` or custom ANSI strings.**

Outfancy is a lightweight Python library for rendering formatted tables in the terminal. Because the library renders cells as literal strings without additional processing, you can add ANSI colors to table cells by embedding escape sequences directly in your data strings.

## How Color Handling Works in the Rendering Pipeline

Outfancy does not provide a dedicated styling API. Instead, it treats any ANSI escape sequences in your data as literal text. The library strips these codes only when necessary for layout calculations, ensuring your colors appear in the final output while maintaining proper column alignment.

In [`outfancy/widgets.py`](https://github.com/carlosplanchon/outfancy/blob/main/outfancy/widgets.py), the `remove_colors` function (lines 15-27) uses a regular expression to strip `\x1b[...` escape sequences. This function is called exclusively by `printed_length` (lines 99-103), which calculates the visual width of cell content for alignment purposes. Because `remove_colors` operates only during width measurement—not during the actual string concatenation—the ANSI codes remain intact in the final table output produced by [`outfancy/table.py`](https://github.com/carlosplanchon/outfancy/blob/main/outfancy/table.py).

The `render` method in [`outfancy/table.py`](https://github.com/carlosplanchon/outfancy/blob/main/outfancy/table.py) builds the table by joining these pre-colored strings, meaning whatever color codes you embed are preserved verbatim in the terminal output.

## Using the Built-in Color Palette

The [`outfancy/colors.py`](https://github.com/carlosplanchon/outfancy/blob/main/outfancy/colors.py) file (lines 3-31) defines a ready-made palette of ANSI constants. These follow a naming convention of `{style}_{color}` where style can be `normal`, `bold`, or `strong`, and color includes standard terminal colors like `red`, `green`, `blue`, and `violet`.

Available constants include:
- `normal_red`, `normal_green`, `normal_blue` — Standard foreground colors
- `bold_normal_blue`, `bold_strong_green` — Bold and high-intensity variants
- `normal_reset`, `bold_normal_reset`, `bold_strong_reset` — Style reset codes

Import the palette and wrap your cell values with the appropriate opening and reset codes:

```python
from outfancy.table import Table
from outfancy import colors

# Wrap cell values with color codes

data = [
    (f"{colors.normal_red}Critical{colors.normal_reset}", "Error", "99"),
    (f"{colors.normal_green}Stable{colors.normal_reset}", "OK", "42"),
    (f"{colors.bold_strong_yellow}Warning{colors.bold_strong_reset}", "Check", "10")
]

tbl = Table()
print(tbl.render(data))

```

## Coloring Table Headers

Headers defined via the `label_list` parameter accept colored strings through the same mechanism. Because labels pass through the same rendering pipeline as data cells, you can apply ANSI codes to column titles to create visually distinct header rows:

```python
labels = [
    f"{colors.bold_normal_violet}Status{colors.bold_normal_reset}",
    f"{colors.bold_normal_violet}Message{colors.bold_normal_reset}",
    f"{colors.bold_normal_violet}Code{colors.bold_normal_reset}"
]

print(tbl.render(data, label_list=labels))

```

## Working with Custom ANSI Codes

If the built-in palette lacks the specific color you need, you can embed raw ANSI escape sequences directly. This is useful for 256-color or RGB terminal colors:

```python

# 256-color orange

custom_orange = "\x1b[38;5;208m"
reset = "\x1b[0m"

data = [
    (f"{custom_orange}Custom{reset}", "Standard", "Data")
]

```

When using custom codes, always include a reset sequence (such as `\x1b[0m` or `colors.normal_reset`) at the end of each colored segment to prevent the styling from bleeding into subsequent cells or text.

## Summary

- Outfancy renders cell content literally, preserving any ANSI escape sequences you embed in your data strings.
- The `remove_colors` function in [`outfancy/widgets.py`](https://github.com/carlosplanchon/outfancy/blob/main/outfancy/widgets.py) (lines 15-27) strips codes only during width calculation via `printed_length`, ensuring columns align correctly despite invisible color codes.
- Import pre-defined color constants from [`outfancy/colors.py`](https://github.com/carlosplanchon/outfancy/blob/main/outfancy/colors.py) or use custom `\x1b[` sequences for full color control.
- Apply reset codes after each colored segment to isolate styling to specific cells.
- Headers support the same coloring technique via the `label_list` parameter.

## Frequently Asked Questions

### Does Outfancy provide a dedicated API for styling individual cells?

No. According to the source code in [`outfancy/table.py`](https://github.com/carlosplanchon/outfancy/blob/main/outfancy/table.py), the library does not implement cell-level styling methods. You add colors by embedding ANSI escape sequences directly into the string values you pass to `Table.render`.

### Will ANSI color codes break table alignment?

No. The `printed_length` function in [`outfancy/widgets.py`](https://github.com/carlosplanchon/outfancy/blob/main/outfancy/widgets.py) (lines 99-103) automatically removes color codes when calculating the visual width of each cell. This ensures the column widths are computed based on the actual character count, not the length of the escape sequences, keeping your table properly aligned.

### Can I color the table headers separately from the data rows?

Yes. The `label_list` parameter in `Table.render` accepts strings, so you can wrap your header labels with the same ANSI color constants used for cell data. These labels undergo the same rendering process as body cells.

### How do I reset colors after styling a specific cell?

Append a reset code immediately after the colored text. Use `colors.normal_reset` for standard colors, `colors.bold_normal_reset` for bold styles, or `colors.bold_strong_reset` for high-intensity bold colors. Alternatively, use the universal `\x1b[0m` reset code to return to default terminal styling.