mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
Support multiple CSS files (#1079)
* Support multiple CSS paths * Update a type to match docstring * Ensure the demo app still works * Use absolute paths in tests to (hopefully) appease Windows * Notes about CSS changes in guide/docstrings, small grammar/typos fixes * Move snapshot apps into snapshot_tests dir, improve messaging in snapshot output, add test for multiple css files interacting with classvar CSS * Ensure consistent snapshot naming cross-platform * Use rpartition instead of partition in import_app * Fix handling of import_app when colon in arg * Support paths containing Windows drive names in import_app * Add note on new relative paths in snap_compare * Update docs/guide/CSS.md Co-authored-by: Will McGugan <willmcgugan@gmail.com> * Fix formatting * Update CHANGELOG to mention CSS_PATH supporting a list Co-authored-by: Will McGugan <willmcgugan@gmail.com>
This commit is contained in:
@@ -4,7 +4,7 @@ Textual uses CSS to apply style to widgets. If you have any exposure to web deve
|
||||
|
||||
## Stylesheets
|
||||
|
||||
CSS stands for _Cascading Stylesheets_. A stylesheet is a list of styles and rules about how those styles should be applied to a web page. In the case of Textual, the stylesheet applies [styles](./styles.md) to widgets but otherwise it is the same idea.
|
||||
CSS stands for _Cascading Stylesheets_. A stylesheet is a list of styles and rules about how those styles should be applied to a web page. In the case of Textual, the stylesheet applies [styles](./styles.md) to widgets, but otherwise it is the same idea.
|
||||
|
||||
When Textual loads CSS it sets attributes on your widgets' `style` object. The effect is the same as if you had set attributes in Python.
|
||||
|
||||
@@ -48,7 +48,7 @@ Header {
|
||||
}
|
||||
```
|
||||
|
||||
The lines inside the curly braces contains CSS _rules_, which consist of a rule name and rule value separated by a colon and ending in a semi-colon. Such rules are typically written one per line, but you could add additional rules as long as they are separated by semi-colons.
|
||||
The lines inside the curly braces contains CSS _rules_, which consist of a rule name and rule value separated by a colon and ending in a semicolon. Such rules are typically written one per line, but you could add additional rules as long as they are separated by semicolons.
|
||||
|
||||
The first rule in the above example reads `"dock: top;"`. The rule name is `dock` which tells Textual to place the widget on an edge of the screen. The text after the colon is `top` which tells Textual to dock to the _top_ of the screen. Other valid values for `dock` are "right", "bottom", or "left"; but "top" is most appropriate for a header.
|
||||
|
||||
@@ -93,7 +93,7 @@ This doesn't look much like a tree yet. Let's add a header and a footer to this
|
||||
```{.textual path="docs/examples/guide/dom2.py"}
|
||||
```
|
||||
|
||||
With a header and a footer widget the DOM looks the this:
|
||||
With a header and a footer widget the DOM looks like this:
|
||||
|
||||
<div class="excalidraw">
|
||||
--8<-- "docs/images/dom2.excalidraw.svg"
|
||||
@@ -132,7 +132,7 @@ Here's the output from this example:
|
||||
|
||||
```
|
||||
|
||||
You may recognize some of the elements in the above screenshot, but it doesn't quite look like a dialog. This is because we haven't added a stylesheet.
|
||||
You may recognize some elements in the above screenshot, but it doesn't quite look like a dialog. This is because we haven't added a stylesheet.
|
||||
|
||||
## CSS files
|
||||
|
||||
@@ -142,7 +142,8 @@ To add a stylesheet set the `CSS_PATH` classvar to a relative path:
|
||||
--8<-- "docs/examples/guide/dom4.py"
|
||||
```
|
||||
|
||||
You may have noticed that some of the constructors have additional keyword arguments: `id` and `classes`. These are used by the CSS to identify parts of the DOM. We will cover these in the next section.
|
||||
You may have noticed that some constructors have additional keyword arguments: `id` and `classes`.
|
||||
These are used by the CSS to identify parts of the DOM. We will cover these in the next section.
|
||||
|
||||
Here's the CSS file we are applying:
|
||||
|
||||
@@ -158,6 +159,10 @@ With the CSS in place, the output looks very different:
|
||||
|
||||
```
|
||||
|
||||
### Using multiple CSS files
|
||||
|
||||
You can also set the `CSS_PATH` class variable to a list of paths. Textual will combine the rules from all of the supplied paths.
|
||||
|
||||
### Why CSS?
|
||||
|
||||
It is reasonable to ask why use CSS at all? Python is a powerful and expressive language. Wouldn't it be easier to set styles in your `.py` files?
|
||||
@@ -178,7 +183,7 @@ Being able to iterate on the design without restarting the application makes it
|
||||
|
||||
A selector is the text which precedes the curly braces in a set of rules. It tells Textual which widgets it should apply the rules to.
|
||||
|
||||
Selectors can target a kind of widget or a very specific widget. For instance you could have a selector that modifies all buttons, or you could target an individual button used in one dialog. This gives you a lot of flexibility in customizing your user interface.
|
||||
Selectors can target a kind of widget or a very specific widget. For instance, you could have a selector that modifies all buttons, or you could target an individual button used in one dialog. This gives you a lot of flexibility in customizing your user interface.
|
||||
|
||||
Let's look at the selectors supported by Textual CSS.
|
||||
|
||||
@@ -201,7 +206,7 @@ Button {
|
||||
}
|
||||
```
|
||||
|
||||
The type selector will also match a widget's base classes. Consequently a `Static` selector will also style the button because the `Button` Python class extends `Static`.
|
||||
The type selector will also match a widget's base classes. Consequently, a `Static` selector will also style the button because the `Button` Python class extends `Static`.
|
||||
|
||||
```sass
|
||||
Static {
|
||||
|
||||
Reference in New Issue
Block a user