-
Notifications
You must be signed in to change notification settings - Fork 3
Style
The Style class represents the CSS style declaration of a DOM element. It provides a Python interface to directly manipulate CSS properties, allowing you to change the appearance and layout of HTML elements dynamically.
The Style class is accessed through the style
property of any Element. It allows you to:
- Set and get CSS properties using Python attribute syntax
- Modify element appearance (colors, fonts, layout, etc.)
- Create dynamic styling effects
- Override CSS stylesheet rules
The Style class uses Python's __setattr__
and __getattr__
methods to provide a natural interface for CSS properties:
# Get an element
element = ui.document.getElementById("myElement")
# Set CSS properties
element.style.color = "red"
element.style.backgroundColor = "blue"
element.style.fontSize = "16px"
element.style.display = "none"
# Get CSS properties
current_color = element.style.color
current_display = element.style.display
-
__setattr__(name: str, value: str)
: Sets a CSS style property. The property name should be in camelCase (e.g.,backgroundColor
instead ofbackground-color
). -
__getattr__(name: str) -> str
: Gets the current value of a CSS style property.
CSS properties in the Style class use camelCase naming convention. Here are the most commonly used properties organized by category:
-
display
: Controls how an element is displayed (e.g., "block", "inline", "flex", "grid", "none") -
position
: Sets the positioning method (e.g., "static", "relative", "absolute", "fixed", "sticky") -
top
,right
,bottom
,left
: Sets the position of a positioned element -
zIndex
: Sets the stack order of an element
-
width
,height
: Sets element dimensions -
minWidth
,minHeight
: Sets minimum dimensions -
maxWidth
,maxHeight
: Sets maximum dimensions -
margin
: Sets margin (shorthand for all sides) -
marginTop
,marginRight
,marginBottom
,marginLeft
: Sets individual margins -
padding
: Sets padding (shorthand for all sides) -
paddingTop
,paddingRight
,paddingBottom
,paddingLeft
: Sets individual padding -
boxSizing
: Controls how the total width and height are calculated
-
display
: Set to "flex" to enable flexbox -
flexDirection
: Sets the direction of flex items (e.g., "row", "column") -
justifyContent
: Aligns flex items horizontally (e.g., "center", "space-between") -
alignItems
: Aligns flex items vertically (e.g., "center", "stretch") -
flexWrap
: Controls whether flex items wrap -
flex
: Shorthand for flex-grow, flex-shrink, and flex-basis
-
display
: Set to "grid" to enable grid layout -
gridTemplateColumns
: Defines grid columns -
gridTemplateRows
: Defines grid rows -
gridGap
: Sets gaps between grid items -
gridColumn
: Places an item in grid columns -
gridRow
: Places an item in grid rows
-
color
: Sets text color -
fontSize
: Sets font size (e.g., "16px", "1.2em", "large") -
fontFamily
: Sets font family (e.g., "Arial, sans-serif") -
fontWeight
: Sets font weight (e.g., "normal", "bold", "400", "700") -
fontStyle
: Sets font style (e.g., "normal", "italic", "oblique") -
fontVariant
: Sets font variant (e.g., "normal", "small-caps")
-
textAlign
: Sets text alignment (e.g., "left", "center", "right", "justify") -
textDecoration
: Sets text decoration (e.g., "none", "underline", "line-through") -
textTransform
: Controls text capitalization (e.g., "none", "uppercase", "lowercase", "capitalize") -
lineHeight
: Sets line height -
letterSpacing
: Sets spacing between characters -
wordSpacing
: Sets spacing between words -
whiteSpace
: Controls how whitespace is handled (e.g., "normal", "nowrap", "pre") -
textOverflow
: Controls how overflowed text is displayed (e.g., "clip", "ellipsis")
-
backgroundColor
: Sets background color -
backgroundImage
: Sets background image (e.g., "url('image.jpg')") -
backgroundSize
: Controls background image size (e.g., "cover", "contain", "100px 50px") -
backgroundPosition
: Sets background image position (e.g., "center", "top left") -
backgroundRepeat
: Controls background image repetition (e.g., "repeat", "no-repeat") -
backgroundAttachment
: Sets whether background scrolls with content (e.g., "scroll", "fixed")
-
border
: Sets border (shorthand for width, style, and color) -
borderWidth
: Sets border width -
borderStyle
: Sets border style (e.g., "solid", "dashed", "dotted", "none") -
borderColor
: Sets border color -
borderRadius
: Sets rounded corners -
borderTop
,borderRight
,borderBottom
,borderLeft
: Sets individual borders -
borderTopWidth
,borderRightWidth
,borderBottomWidth
,borderLeftWidth
: Sets individual border widths -
borderTopStyle
,borderRightStyle
,borderBottomStyle
,borderLeftStyle
: Sets individual border styles -
borderTopColor
,borderRightColor
,borderBottomColor
,borderLeftColor
: Sets individual border colors
-
opacity
: Sets transparency level (0.0 to 1.0) -
visibility
: Sets visibility (e.g., "visible", "hidden", "collapse")
-
boxShadow
: Adds shadow to element box -
textShadow
: Adds shadow to text -
filter
: Applies visual effects (e.g., "blur(5px)", "brightness(0.5)")
-
transform
: Applies 2D/3D transformations (e.g., "rotate(45deg)", "scale(1.5)") -
transformOrigin
: Sets transformation origin point
-
transition
: Creates smooth transitions between property changes -
transitionProperty
: Specifies which properties to animate -
transitionDuration
: Sets transition duration -
transitionTimingFunction
: Sets transition timing function -
transitionDelay
: Sets transition delay
-
overflow
: Controls content overflow (e.g., "visible", "hidden", "scroll", "auto") -
overflowX
: Controls horizontal overflow -
overflowY
: Controls vertical overflow
-
cursor
: Sets cursor style (e.g., "pointer", "default", "wait", "not-allowed") -
userSelect
: Controls text selection (e.g., "none", "text", "all") -
pointerEvents
: Controls pointer events (e.g., "auto", "none")
def main(ui):
button = ui.document.getElementById("myButton")
# Basic appearance
button.style.backgroundColor = "#007bff"
button.style.color = "white"
button.style.border = "none"
button.style.padding = "10px 20px"
button.style.borderRadius = "5px"
button.style.cursor = "pointer"
# Typography
button.style.fontSize = "16px"
button.style.fontWeight = "600"
button.style.fontFamily = "Arial, sans-serif"
def main(ui):
container = ui.document.getElementById("container")
# Create a flexible layout
container.style.display = "flex"
container.style.flexDirection = "row"
container.style.justifyContent = "space-between"
container.style.alignItems = "center"
container.style.padding = "20px"
container.style.gap = "15px"
# Make it responsive
container.style.flexWrap = "wrap"
def main(ui):
card = ui.document.getElementById("card")
def on_mouse_enter():
card.style.transform = "scale(1.05)"
card.style.boxShadow = "0 10px 20px rgba(0,0,0,0.2)"
card.style.transition = "all 0.3s ease"
def on_mouse_leave():
card.style.transform = "scale(1)"
card.style.boxShadow = "0 2px 5px rgba(0,0,0,0.1)"
card.addEventListener("mouseenter", on_mouse_enter)
card.addEventListener("mouseleave", on_mouse_leave)
# Initial styling
card.style.transition = "all 0.3s ease"
card.style.cursor = "pointer"
def main(ui):
def apply_dark_theme():
body = ui.document.body
body.style.backgroundColor = "#1a1a1a"
body.style.color = "#ffffff"
# Style all cards
cards = ui.document.getElementsByClassName("card")
for card in cards:
card.style.backgroundColor = "#2d2d2d"
card.style.borderColor = "#444"
card.style.color = "#ffffff"
def apply_light_theme():
body = ui.document.body
body.style.backgroundColor = "#ffffff"
body.style.color = "#000000"
cards = ui.document.getElementsByClassName("card")
for card in cards:
card.style.backgroundColor = "#ffffff"
card.style.borderColor = "#ddd"
card.style.color = "#000000"
# Theme toggle button
theme_btn = ui.document.getElementById("themeToggle")
is_dark = False
def toggle_theme():
nonlocal is_dark
if is_dark:
apply_light_theme()
theme_btn.innerText = "Dark Mode"
else:
apply_dark_theme()
theme_btn.innerText = "Light Mode"
is_dark = not is_dark
theme_btn.addEventListener("click", toggle_theme)
def main(ui):
def validate_input(input_element, is_valid):
if is_valid:
input_element.style.borderColor = "#28a745"
input_element.style.backgroundColor = "#f8fff9"
else:
input_element.style.borderColor = "#dc3545"
input_element.style.backgroundColor = "#fff5f5"
email_input = ui.document.getElementById("email")
def check_email():
email = email_input.value
is_valid = "@" in email and "." in email
validate_input(email_input, is_valid)
email_input.addEventListener("input", check_email)
# Initial styling
email_input.style.transition = "all 0.3s ease"
email_input.style.padding = "10px"
email_input.style.border = "2px solid #ddd"
email_input.style.borderRadius = "4px"
def main(ui):
spinner = ui.document.getElementById("spinner")
# Create a spinning animation using CSS
spinner.style.width = "40px"
spinner.style.height = "40px"
spinner.style.border = "4px solid #f3f3f3"
spinner.style.borderTop = "4px solid #3498db"
spinner.style.borderRadius = "50%"
spinner.style.animation = "spin 2s linear infinite"
# You would need to add the @keyframes rule to your CSS:
# @keyframes spin {
# 0% { transform: rotate(0deg); }
# 100% { transform: rotate(360deg); }
# }
def show_loading():
spinner.style.display = "block"
def hide_loading():
spinner.style.display = "none"
# Example usage
load_btn = ui.document.getElementById("loadBtn")
def handle_load():
show_loading()
# Simulate loading time
ui.htmlwindow.setTimeout(hide_loading, 3000)
load_btn.addEventListener("click", handle_load)
def main(ui):
gallery = ui.document.getElementById("gallery")
# Create a responsive grid
gallery.style.display = "grid"
gallery.style.gridTemplateColumns = "repeat(auto-fit, minmax(200px, 1fr))"
gallery.style.gridGap = "20px"
gallery.style.padding = "20px"
# Add items to the grid
for i in range(12):
item = ui.document.createElement("div")
item.className = "gallery-item"
item.innerText = f"Item {i + 1}"
# Style each item
item.style.backgroundColor = "#f0f0f0"
item.style.padding = "20px"
item.style.textAlign = "center"
item.style.borderRadius = "8px"
item.style.transition = "transform 0.3s ease"
# Add hover effect
def create_hover_handler(element):
def on_hover():
element.style.transform = "translateY(-5px)"
element.style.boxShadow = "0 5px 15px rgba(0,0,0,0.1)"
def on_leave():
element.style.transform = "translateY(0)"
element.style.boxShadow = "none"
element.addEventListener("mouseenter", on_hover)
element.addEventListener("mouseleave", on_leave)
create_hover_handler(item)
gallery.appendChild(item)
When using CSS properties in PyPositron, remember to convert kebab-case to camelCase:
CSS Property | PyPositron Style Property |
---|---|
background-color |
backgroundColor |
font-size |
fontSize |
margin-top |
marginTop |
border-radius |
borderRadius |
z-index |
zIndex |
text-align |
textAlign |
line-height |
lineHeight |
box-shadow |
boxShadow |
-
Use meaningful units: Prefer
px
for precise measurements,em
orrem
for scalable text,%
for responsive layouts. -
Set transitions for smooth effects: Always add
transition
properties when creating hover effects or dynamic style changes. -
Cache style references: If you're making multiple style changes, consider caching the style object:
style = element.style style.color = "red" style.fontSize = "16px" style.padding = "10px"
-
Use CSS classes for complex styling: For complex styles, consider adding/removing CSS classes instead of setting individual properties.
-
Be mindful of performance: Changing many style properties can trigger layout recalculations. Group changes when possible.
-
Validate color values: Ensure color values are valid CSS colors (hex, rgb, rgba, named colors).
-
Use consistent units: Stick to consistent units throughout your application (e.g., always use
px
for borders).
-
Element: The Element class that provides the
style
property - W3Schools CSS Properties: Complete CSS properties reference
- MDN CSS Properties: Comprehensive CSS documentation
- CSS Units Guide: Understanding CSS units