[GH-ISSUE #496] Box component background + border #130

Closed
opened 2026-03-02 23:44:46 +03:00 by kerem · 5 comments
Owner

Originally created by @DennisKo on GitHub (Jan 8, 2026).
Original GitHub issue: https://github.com/anomalyco/opentui/issues/496

How do we correctly style a <box> with a border and a background, so that the background actually spans exactly the component area. I see either the background bleeding out of the container (left box) or a gap inside the box (right box).

Image

I guess its because of the title? I am using @opentui/react + @opentui/core v0.1.69.

import { createCliRenderer } from "@opentui/core";
import { createRoot } from "@opentui/react";

function App() {
  return (
    <box
      flexDirection="row"
      gap={3}
      height="100%"
      backgroundColor="gray"
      padding={3}
    >
      <box
        alignItems="center"
        justifyContent="center"
        width={50}
        height={20}
        border
        borderColor="white"
        backgroundColor="black"
      >
        <text>Hello, World!</text>
      </box>
      <box width={50} height={20} border borderColor="white">
        <box
          backgroundColor="black"
          height="100%"
          width="100%"
          alignItems="center"
          justifyContent="center"
        >
          <text>Hello, World!</text>
        </box>
      </box>
    </box>
  );
}

const renderer = await createCliRenderer();
createRoot(renderer).render(<App />);

Originally created by @DennisKo on GitHub (Jan 8, 2026). Original GitHub issue: https://github.com/anomalyco/opentui/issues/496 How do we correctly style a `<box>` with a border and a background, so that the background actually spans exactly the component area. I see either the background bleeding out of the container (left box) or a gap inside the box (right box). <img width="862" height="393" alt="Image" src="https://github.com/user-attachments/assets/0d7f6d31-8803-4792-b2a0-bc4a3b985405" /> I guess its because of the title? I am using `@opentui/react + @opentui/core` v0.1.69. ```tsx import { createCliRenderer } from "@opentui/core"; import { createRoot } from "@opentui/react"; function App() { return ( <box flexDirection="row" gap={3} height="100%" backgroundColor="gray" padding={3} > <box alignItems="center" justifyContent="center" width={50} height={20} border borderColor="white" backgroundColor="black" > <text>Hello, World!</text> </box> <box width={50} height={20} border borderColor="white"> <box backgroundColor="black" height="100%" width="100%" alignItems="center" justifyContent="center" > <text>Hello, World!</text> </box> </box> </box> ); } const renderer = await createCliRenderer(); createRoot(renderer).render(<App />); ```
kerem closed this issue 2026-03-02 23:44:46 +03:00
Author
Owner

@kommander commented on GitHub (Jan 8, 2026):

You can use customBorderChars to use Unicode borders.

<!-- gh-comment-id:3725210557 --> @kommander commented on GitHub (Jan 8, 2026): You can use `customBorderChars` to use Unicode borders.
Author
Owner

@DennisKo commented on GitHub (Jan 9, 2026):

You can use customBorderChars to use Unicode borders.

I don't see how this helps with the background problem. I tried using some custom borders and the background gap/bleeding remains.

<!-- gh-comment-id:3728438272 --> @DennisKo commented on GitHub (Jan 9, 2026): > You can use customBorderChars to use Unicode borders. I don't see how this helps with the background problem. I tried using some custom borders and the background gap/bleeding remains.
Author
Owner

@msmps commented on GitHub (Jan 9, 2026):

Ink has the same problem (see below)!

Image

A solution is to set background color of the terminal via the renderer to match the background color of the box which gives this illusion (left)

Source
import { createCliRenderer } from "@opentui/core";
import { createRoot } from "@opentui/react";

function App() {
  return (
    <box
      flexDirection="row"
      gap={3}
      height="100%"
      backgroundColor="black"
      padding={3}
    >
      <box
        alignItems="center"
        justifyContent="center"
        width={50}
        height={20}
        border
        borderColor="white"
        backgroundColor="black"
      >
        <text>Hello, World!</text>
      </box>

      <box
        alignItems="center"
        justifyContent="center"
        width={50}
        height={20}
        border
        borderColor="white"
        backgroundColor="blue"
      >
        <text>Hello, World!</text>
      </box>
    </box>
  );
}

const renderer = await createCliRenderer();
renderer.setBackgroundColor("black");
createRoot(renderer).render(<App />);
Image
<!-- gh-comment-id:3728761285 --> @msmps commented on GitHub (Jan 9, 2026): Ink has the same problem (_see below_)! <img width="462" height="398" alt="Image" src="https://github.com/user-attachments/assets/7ad2b6a6-5abe-49da-b176-de53d3b0d8d3" /> A solution is to set background color of the terminal via the renderer to match the background color of the box which gives this illusion (_left_) <details> <summary>Source</summary> ```tsx import { createCliRenderer } from "@opentui/core"; import { createRoot } from "@opentui/react"; function App() { return ( <box flexDirection="row" gap={3} height="100%" backgroundColor="black" padding={3} > <box alignItems="center" justifyContent="center" width={50} height={20} border borderColor="white" backgroundColor="black" > <text>Hello, World!</text> </box> <box alignItems="center" justifyContent="center" width={50} height={20} border borderColor="white" backgroundColor="blue" > <text>Hello, World!</text> </box> </box> ); } const renderer = await createCliRenderer(); renderer.setBackgroundColor("black"); createRoot(renderer).render(<App />); ``` </details> <img width="980" height="511" alt="Image" src="https://github.com/user-attachments/assets/167cc6ea-9e7e-4414-91ac-bdd29f5fb3c0" />
Author
Owner

@DennisKo commented on GitHub (Jan 9, 2026):

A solution is to set background color of the terminal via the renderer to match the background color of the box which gives this illusion (left)

That kind of defeats the purpose of a background in a box. Is this such an exotic use case?

<!-- gh-comment-id:3730436945 --> @DennisKo commented on GitHub (Jan 9, 2026): > A solution is to set background color of the terminal via the renderer to match the background color of the box which gives this illusion (left) That kind of defeats the purpose of a background in a box. Is this such an exotic use case?
Author
Owner

@peter-wasilko commented on GitHub (Feb 13, 2026):

I don't see why this was closed, we still can't make a button widget using the rounded borderStyle and set a background color on it without the background color spilling out over the frame line as a solid unrounded rectangle. I think we need a custom color font to draw the boder line so outside the line is solid black, the line itself is the border color, and inside the line is transparent to show the component's background color. Otherwise we can't have solid looking button with a colored fill. If there is some existing unicode hack to address this issue, it really needs to be discussed in the docs. Or perhaps there are some line drawing Terminal Escape Codes that could generate the desired effect.

<!-- gh-comment-id:3894376206 --> @peter-wasilko commented on GitHub (Feb 13, 2026): I don't see why this was closed, we still can't make a button widget using the rounded borderStyle and set a background color on it without the background color spilling out over the frame line as a solid unrounded rectangle. I think we need a custom color font to draw the boder line so outside the line is solid black, the line itself is the border color, and inside the line is transparent to show the component's background color. Otherwise we can't have solid looking button with a colored fill. If there is some existing unicode hack to address this issue, it really needs to be discussed in the docs. Or perhaps there are some line drawing Terminal Escape Codes that could generate the desired effect.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/opentui#130
No description provided.