mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
color docs
This commit is contained in:
@@ -1,30 +1,52 @@
|
|||||||
# Styles
|
# Styles
|
||||||
|
|
||||||
Textual provides a large number of *styles* you can use to customize how your app looks and feels. In this chapter will will look at how you can edit styles in your applications.
|
In this chapter will explore how you can apply styles to your application to create beautiful user interfaces.
|
||||||
|
|
||||||
|
|
||||||
## Styles object
|
## Styles object
|
||||||
|
|
||||||
Every widget class in Textual provides a `styles` object which contains a number of writable attributes. You can write to any of these attributes and Textual will update the screen accordingly.
|
Every Textual widget class provides a `styles` object which contains a number of attributes. These attributes tell Textual how the widget should be displayed, and how it should be positioned on the screen relative to other widgets.
|
||||||
|
|
||||||
Let's look at a simple example which sets the styles on the `screen` (a special widget that represents the screen).
|
!!! note
|
||||||
|
|
||||||
|
These docs use the term *screen* to describe the contents of the terminal, which will typically be a window on your desktop.
|
||||||
|
|
||||||
|
If you write to any styles attribute the screen will update accordingly.
|
||||||
|
|
||||||
|
Let's look at a simple example which sets the styles on `screen` (a special widget that represents the screen).
|
||||||
|
|
||||||
```python title="screen.py" hl_lines="6-7"
|
```python title="screen.py" hl_lines="6-7"
|
||||||
--8<-- "docs/examples/guide/styles/screen.py"
|
--8<-- "docs/examples/guide/styles/screen.py"
|
||||||
```
|
```
|
||||||
|
|
||||||
The first line sets [background](../styles/background.md) to `"darkblue"` which will change the background color to dark blue. There are a few other ways of setting color which we will explore later.
|
The first line sets the [background](../styles/background.md) style to `"darkblue"` which will change the background color to dark blue. There are a few other ways of setting color which we will explore later.
|
||||||
|
|
||||||
The second line sets [border](../styles/border.md) to a tuple of `("heavy", "white")` which tells Textual to draw a white border with a style of `"heavy"`. Running this code will show the following:
|
The second line sets [border](../styles/border.md) to a tuple of `("heavy", "white")` which tells Textual to draw a white border with a style of `"heavy"`. Running this code will show the following:
|
||||||
|
|
||||||
```{.textual path="docs/examples/guide/styles/screen.py"}
|
```{.textual path="docs/examples/guide/styles/screen.py"}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Styling widgets
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Colors
|
## Colors
|
||||||
|
|
||||||
The [color](../styles/color.md) property set the color of text on a widget. The [background](..styles/background/md) property sets the color of the background (under the text).
|
There are a number of style attribute which accept colors. The most commonly used arel be [color](../styles/color.md) which sets the default color of text on a widget, and [background](..styles/background/md) which sets the background color (under the text).
|
||||||
|
|
||||||
|
You can set a color value to one of a number of pre-defined color constants, such as "crimson", "lime", and "palegreen". You can find a full list in the [Color reference](../reference/color.md#textual.color--named-colors).
|
||||||
|
|
||||||
|
Here's how you would set the screen background to lime:
|
||||||
|
|
||||||
|
```python
|
||||||
|
self.screen.background = "lime"
|
||||||
|
```
|
||||||
|
|
||||||
|
In addition to color names, there are other ways you can specify a color in Textual (which give you access to all 16.7 million colors a typical monitor can display).
|
||||||
|
|
||||||
|
- RGB hex colors starts with a `#` followed by three pairs of one or two hex digits; one for the red, green, and blue color components. For example, `#f00` is an intense red color, and `#9932CC` is *dark orchid*.
|
||||||
|
- RGB decimal color start with `rgb` followed by a tuple of three numbers in the range 0 to 255. For example `rgb(255,0,0)` is intense red, and `rgb(153,50,204)` is *dark orchid*.
|
||||||
|
- HSL colors start with `hsl` followed by a tuple of three colors in the range 0 to 255, representing the Hue Saturation and Lightness. For example `hsl(0,100%,50%)` is intense red and `hsl(280,60%,49%)` is *dark orchid*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
1
docs/reference/screen.md
Normal file
1
docs/reference/screen.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
::: textual.screen
|
||||||
@@ -10,16 +10,19 @@ The following named colors are used by the [parse][textual.color.Color.parse] me
|
|||||||
|
|
||||||
```{.rich title="colors"}
|
```{.rich title="colors"}
|
||||||
from textual._color_constants import COLOR_NAME_TO_RGB
|
from textual._color_constants import COLOR_NAME_TO_RGB
|
||||||
|
from textual.color import Color
|
||||||
from rich.table import Table
|
from rich.table import Table
|
||||||
from rich.text import Text
|
from rich.text import Text
|
||||||
table = Table("Name", "RGB", "Color", expand=True, highlight=True)
|
table = Table("Name", "hex", "RGB", "Color", expand=True, highlight=True)
|
||||||
|
|
||||||
for name, triplet in sorted(COLOR_NAME_TO_RGB.items()):
|
for name, triplet in sorted(COLOR_NAME_TO_RGB.items()):
|
||||||
if len(triplet) != 3:
|
if len(triplet) != 3:
|
||||||
continue
|
continue
|
||||||
|
color = Color(*triplet)
|
||||||
r, g, b = triplet
|
r, g, b = triplet
|
||||||
table.add_row(
|
table.add_row(
|
||||||
f'"{name}"',
|
f'"{name}"',
|
||||||
|
f"{color.hex}",
|
||||||
f"rgb({r}, {g}, {b})",
|
f"rgb({r}, {g}, {b})",
|
||||||
Text(" ", style=f"on rgb({r},{g},{b})")
|
Text(" ", style=f"on rgb({r},{g},{b})")
|
||||||
)
|
)
|
||||||
@@ -64,6 +67,16 @@ class HLS(NamedTuple):
|
|||||||
s: float
|
s: float
|
||||||
"""Saturation"""
|
"""Saturation"""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def css(self) -> str:
|
||||||
|
"""HLS in css format."""
|
||||||
|
h, l, s = self
|
||||||
|
|
||||||
|
def as_str(number: float) -> str:
|
||||||
|
return f"{number:.1f}".rstrip("0").rstrip(".")
|
||||||
|
|
||||||
|
return f"hsl({as_str(h*360)},{as_str(s*100)}%,{as_str(l*100)}%)"
|
||||||
|
|
||||||
|
|
||||||
class HSV(NamedTuple):
|
class HSV(NamedTuple):
|
||||||
"""A color in HSV format."""
|
"""A color in HSV format."""
|
||||||
@@ -99,11 +112,11 @@ hsla{OPEN_BRACE}({DECIMAL}{COMMA}{PERCENT}{COMMA}{PERCENT}{COMMA}{DECIMAL}){CLOS
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Fast way to split a string of 6 characters in to 3 pairs of 2 characters
|
# Fast way to split a string of 6 characters in to 3 pairs of 2 characters
|
||||||
split_pairs3: Callable[[str], tuple[str, str, str]] = itemgetter(
|
_split_pairs3: Callable[[str], tuple[str, str, str]] = itemgetter(
|
||||||
slice(0, 2), slice(2, 4), slice(4, 6)
|
slice(0, 2), slice(2, 4), slice(4, 6)
|
||||||
)
|
)
|
||||||
# Fast way to split a string of 8 characters in to 4 pairs of 2 characters
|
# Fast way to split a string of 8 characters in to 4 pairs of 2 characters
|
||||||
split_pairs4: Callable[[str], tuple[str, str, str, str]] = itemgetter(
|
_split_pairs4: Callable[[str], tuple[str, str, str, str]] = itemgetter(
|
||||||
slice(0, 2), slice(2, 4), slice(4, 6), slice(6, 8)
|
slice(0, 2), slice(2, 4), slice(4, 6), slice(6, 8)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -237,7 +250,7 @@ class Color(NamedTuple):
|
|||||||
"""Get the color as HLS.
|
"""Get the color as HLS.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
HLS:
|
HLS: Color in HLS format.
|
||||||
"""
|
"""
|
||||||
r, g, b = self.normalized
|
r, g, b = self.normalized
|
||||||
return HLS(*rgb_to_hls(r, g, b))
|
return HLS(*rgb_to_hls(r, g, b))
|
||||||
@@ -350,7 +363,7 @@ class Color(NamedTuple):
|
|||||||
- `rgb(RED,GREEN,BLUE)`
|
- `rgb(RED,GREEN,BLUE)`
|
||||||
- `rgba(RED,GREEN,BLUE,ALPHA)`
|
- `rgba(RED,GREEN,BLUE,ALPHA)`
|
||||||
- `hsl(RED,GREEN,BLUE)`
|
- `hsl(RED,GREEN,BLUE)`
|
||||||
- `hsl(RED,GREEN,BLUE,ALPHA)`
|
- `hsla(RED,GREEN,BLUE,ALPHA)`
|
||||||
|
|
||||||
All other text will raise a `ColorParseError`.
|
All other text will raise a `ColorParseError`.
|
||||||
|
|
||||||
@@ -402,10 +415,10 @@ class Color(NamedTuple):
|
|||||||
int(f"{a}{a}", 16) / 255.0,
|
int(f"{a}{a}", 16) / 255.0,
|
||||||
)
|
)
|
||||||
elif rgb_hex is not None:
|
elif rgb_hex is not None:
|
||||||
r, g, b = [int(pair, 16) for pair in split_pairs3(rgb_hex)]
|
r, g, b = [int(pair, 16) for pair in _split_pairs3(rgb_hex)]
|
||||||
color = cls(r, g, b, 1.0)
|
color = cls(r, g, b, 1.0)
|
||||||
elif rgba_hex is not None:
|
elif rgba_hex is not None:
|
||||||
r, g, b, a = [int(pair, 16) for pair in split_pairs4(rgba_hex)]
|
r, g, b, a = [int(pair, 16) for pair in _split_pairs4(rgba_hex)]
|
||||||
color = cls(r, g, b, a / 255.0)
|
color = cls(r, g, b, a / 255.0)
|
||||||
elif rgb is not None:
|
elif rgb is not None:
|
||||||
r, g, b = [clamp(int(float(value)), 0, 255) for value in rgb.split(",")]
|
r, g, b = [clamp(int(float(value)), 0, 255) for value in rgb.split(",")]
|
||||||
|
|||||||
Reference in New Issue
Block a user