Bubbletea and stacking styles with Lipgloss?

want to achieve: Produce colored output over other colored output, with underlying uncovered output preserved.

my attempt: bellow, where model is Bubbletea’s model interface implementation

import gloss "github.com/charmbracelet/lipgloss"

func (m model) View() string {
	diagStyle := gloss.NewStyle().
		Background(gloss.Color("#0000aa"))
	r1Style := gloss.NewStyle().
		Inherit(diagStyle).
		Foreground(gloss.Color("#ffff00"))
	r2Style := gloss.NewStyle().
		Inherit(diagStyle).
		Foreground(gloss.Color("#ff0000"))
	r3Style := gloss.NewStyle().
		Inherit(diagStyle).
		Foreground(gloss.Color("#ffffff"))
	out := diagStyle.
		Width(30).
		Height(5).
		Padding(1, 2).
		Render(
			gloss.JoinVertical(gloss.Left,
				r1Style.Render("Alice"),
				r2Style.Render("Bob"),
				r3Style.Render("Charlie"),
			),
		)
	return out
}

produces following output with artifacts:

How to fix it, to preserve blueish background color of underlying diagStyle? (after Alice and Bob)

I think it would help to analyze what happens with the ANSI codes emitted by the program. I’m pretty sure that r1Style.Render("Alice") etc. emit a reset code after the string and diagStyle only reverts the background to blue outside the box rendered by JoinVertical. I would also test what happens when you align right or center.

Anyway, how I’d try to fix it:

  • Pad the strings with spaces.
  • Use a lipgloss table instead of JoinVertical, styled with blue background and no borders.

You could also submit a lipgloss issue with this example. It is more intuitive to have transparent padding in JoinVertical, although in the light of my hypothesis above it may not be trivial to implement.