You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

351 lines
9.7 KiB

Styling
=======
BadGUI provides powerful styling capabilities inspired by NiceGUI, allowing you to style components using CSS classes, component properties, and inline styles.
Styling Methods
---------------
BadGUI components support three main styling methods:
Classes Method
~~~~~~~~~~~~~~
The ``.classes()`` method manages CSS classes, supporting Tailwind CSS, Quasar classes, and custom CSS classes.
**Basic Usage:**
.. code-block:: python
# Add classes
label = bg.label("Styled Text")
label.classes("text-h4 text-primary q-mb-md")
**Method Chaining:**
.. code-block:: python
bg.label("Chained Styling")\
.classes("text-center")\
.classes("text-bold")\
.classes("bg-blue-100 p-4")
**Advanced Class Management:**
.. code-block:: python
label = bg.label("Dynamic Classes")
# Add specific classes
label.classes(add="border rounded")
# Remove classes
label.classes(remove="bg-blue-100")
# Replace all classes
label.classes(replace="text-h3 text-success")
Props Method
~~~~~~~~~~~~
The ``.props()`` method sets component properties, supporting both string and keyword syntax.
**String Syntax:**
.. code-block:: python
# Boolean properties
button = bg.button("Button")
button.props("outline rounded push")
# Key-value properties
input_field = bg.input()
input_field.props("color=primary dense filled")
# Quoted values
input_field.props('label="Enter your name" placeholder="Full name"')
**Keyword Syntax:**
.. code-block:: python
button.props(
color="primary",
outline=True,
disabled=False,
icon="star"
)
**Mixed Syntax:**
.. code-block:: python
component.props("dense filled", color="teal", label="Advanced Input")
Style Method
~~~~~~~~~~~~
The ``.style()`` method applies inline CSS styles.
**CSS String Syntax:**
.. code-block:: python
label = bg.label("Custom Styled")
label.style("color: #ff6b6b; font-size: 18px; padding: 10px")
**Keyword Syntax:**
.. code-block:: python
# camelCase is automatically converted to kebab-case
label.style(
color="#4ecdc4",
backgroundColor="#f7f7f7",
fontSize="16px",
borderLeft="4px solid #4ecdc4"
)
**Style Chaining:**
.. code-block:: python
bg.label("Multi-Style")\
.style("color: red; background: yellow")\
.style("padding: 10px; border-radius: 5px")
CSS Frameworks
--------------
BadGUI works seamlessly with popular CSS frameworks:
Quasar Classes
~~~~~~~~~~~~~~
BadGUI generates Quasar Framework projects, giving you access to all Quasar CSS classes:
.. code-block:: python
# Typography
bg.label("Heading").classes("text-h3 text-weight-bold text-primary")
bg.label("Body").classes("text-body1 text-grey-7")
# Spacing
bg.button("Spaced").classes("q-ma-lg q-pa-md")
# Colors
bg.label("Colored").classes("bg-positive text-white")
# Flexbox utilities
with bg.row().classes("justify-center items-center q-gutter-md"):
bg.button("Centered 1")
bg.button("Centered 2")
Tailwind CSS
~~~~~~~~~~~~
BadGUI supports Tailwind CSS classes out of the box:
.. code-block:: python
# Layout
with bg.row().classes("flex flex-wrap gap-4"):
bg.label("Item 1").classes("flex-1 bg-blue-100 p-4 rounded")
bg.label("Item 2").classes("flex-1 bg-green-100 p-4 rounded")
# Typography
bg.label("Title").classes("text-2xl font-bold text-gray-800")
bg.label("Subtitle").classes("text-lg text-gray-600 italic")
# Responsive design
bg.button("Responsive").classes("w-full md:w-auto px-6 py-2")
Custom CSS
~~~~~~~~~~
Add your own custom CSS classes:
.. code-block:: python
# Assuming you have custom CSS defined
bg.label("Custom").classes("my-custom-gradient-text shadow-custom")
# Mix with framework classes
bg.button("Mixed").classes("q-btn-primary my-custom-hover-effect")
Layout Styling
--------------
Style layout containers for complex designs:
Responsive Layouts
~~~~~~~~~~~~~~~~~~
.. code-block:: python
with bg.row().classes("row q-col-gutter-md") as responsive_row:
responsive_row.style("min-height: 300px")
# Responsive columns
with bg.column().classes("col-12 col-md-6 col-lg-4"):
bg.label("Column 1").classes("bg-blue-1 p-4 full-height")
with bg.column().classes("col-12 col-md-6 col-lg-4"):
bg.label("Column 2").classes("bg-green-1 p-4 full-height")
with bg.column().classes("col-12 col-md-12 col-lg-4"):
bg.label("Column 3").classes("bg-red-1 p-4 full-height")
Grid Layouts
~~~~~~~~~~~~
.. code-block:: python
# CSS Grid using Tailwind
with bg.row().classes("grid grid-cols-1 md:grid-cols-3 gap-4") as grid:
for i in range(6):
bg.label(f"Grid Item {i+1}").classes("bg-gray-100 p-4 rounded text-center")
Flexbox Layouts
~~~~~~~~~~~~~~~
.. code-block:: python
# Flex container
with bg.row().classes("flex justify-between items-center q-pa-md") as flex_row:
flex_row.style("background: linear-gradient(45deg, #f0f0f0, #e0e0e0)")
bg.label("Left").classes("text-h6")
bg.button("Center").classes("q-btn-primary")
bg.label("Right").classes("text-caption")
Advanced Styling
----------------
Dynamic Styling
~~~~~~~~~~~~~~~
Create dynamic styles based on conditions:
.. code-block:: python
def create_status_label(text, status):
label = bg.label(text)
if status == "success":
label.classes("text-positive bg-light-green-1 q-pa-sm rounded")
elif status == "warning":
label.classes("text-warning bg-orange-1 q-pa-sm rounded")
elif status == "error":
label.classes("text-negative bg-red-1 q-pa-sm rounded")
else:
label.classes("text-grey-7 bg-grey-1 q-pa-sm rounded")
return label
# Usage
with bg.page("/", "StatusDemo"):
create_status_label("Success Message", "success")
create_status_label("Warning Message", "warning")
create_status_label("Error Message", "error")
Theme Integration
~~~~~~~~~~~~~~~~~
Work with Quasar's theming system:
.. code-block:: python
# Using theme colors
bg.button("Primary").props("color=primary")
bg.button("Secondary").props("color=secondary")
bg.button("Accent").props("color=accent")
# Dark mode classes
bg.label("Dark Mode Text").classes("text-white bg-dark q-pa-md")
Animations and Transitions
~~~~~~~~~~~~~~~~~~~~~~~~~~
Add CSS animations and transitions:
.. code-block:: python
# Hover effects
bg.button("Hover Me").classes("transition-all duration-300 hover:scale-105")
# Loading states
bg.button("Loading").props("loading").classes("q-btn-primary")
# Custom animations (requires custom CSS)
bg.label("Animated").classes("fade-in-animation pulse-on-hover")
Best Practices
--------------
1. **Use Semantic Classes**: Prefer semantic class names over purely visual ones
2. **Mobile First**: Design for mobile devices first, then add desktop styles
3. **Consistent Spacing**: Use consistent spacing units (Quasar's spacing system)
4. **Color Harmony**: Stick to a consistent color palette
5. **Performance**: Avoid excessive inline styles; prefer CSS classes
**Good Example:**
.. code-block:: python
# Good: Semantic, consistent, mobile-first
bg.label("Article Title").classes("text-h4 q-mb-md text-weight-medium")
bg.label("Article Content").classes("text-body1 text-grey-8 line-height-md")
**Avoid:**
.. code-block:: python
# Avoid: Too specific, hard to maintain
bg.label("Title").style("font-size: 24px; margin-bottom: 16px; font-weight: 500; color: #1976d2")
Debugging Styles
----------------
Tips for debugging styling issues:
1. **Inspect Generated HTML**: Check the generated Vue components in the build output
2. **Browser DevTools**: Use browser inspector to see applied styles
3. **Class Conflicts**: Be aware of CSS specificity and class order
4. **Framework Documentation**: Refer to Quasar and Tailwind documentation
Example: Complete Styled Page
-----------------------------
Here's a complete example showcasing various styling techniques:
.. code-block:: python
import badgui as bg
with bg.page("/", "StyledDemo", "Styling Demo"):
# Header
bg.label("Styling Showcase").classes("text-h2 text-center text-primary q-mb-xl")
# Hero section
with bg.row().classes("bg-gradient-to-r from-blue-400 to-purple-500 text-white q-pa-xl rounded-lg q-mb-lg") as hero:
with bg.column().classes("items-center text-center"):
bg.label("Welcome to BadGUI").classes("text-h3 q-mb-md")
bg.label("Beautiful UIs with Python").classes("text-h6 opacity-80 q-mb-lg")
bg.button("Get Started").classes("q-btn-lg").props("color=white text-color=primary")
# Feature cards
with bg.row().classes("q-col-gutter-lg q-mb-lg"):
for i, feature in enumerate(["Fast", "Simple", "Powerful"]):
with bg.column().classes("col-12 col-md-4"):
with bg.column().classes("bg-white rounded-lg shadow-2 q-pa-lg items-center text-center") as card:
card.style("border-top: 4px solid #1976d2")
bg.label(feature).classes("text-h5 text-primary q-mb-md")
bg.label(f"Feature {i+1} description").classes("text-body2 text-grey-7")
# Call to action
with bg.row().classes("justify-center q-mt-xl"):
bg.button("Learn More").classes("q-btn-lg q-btn-primary q-mr-md")
bg.button("Examples").classes("q-btn-lg q-btn-outline")
bg.build("styled-demo")