Personalización visual y temas

Intermedio
Streamlit
Streamlit
Actualizado: 03/09/2025

Customización de CSS y estilos con st.markdown

Streamlit permite personalizar la apariencia de las aplicaciones más allá de los estilos predeterminados mediante la función st.markdown(). Esta función no solo renderiza texto en formato markdown, sino que también puede interpretar código HTML y CSS cuando se habilita el parámetro correspondiente.

La función st.markdown() acepta un parámetro llamado unsafe_allow_html que, cuando se establece como True, permite incluir etiquetas HTML y estilos CSS directamente en el contenido. Esto abre un amplio abanico de posibilidades para personalizar elementos específicos de la interfaz.

Sintaxis básica para estilos personalizados

Para aplicar estilos CSS personalizados, utilizamos la siguiente estructura:

import streamlit as st

# Ejemplo básico de HTML con CSS inline
st.markdown("""
    <div style="background-color: #f0f2f6; padding: 10px; border-radius: 5px;">
        <h3 style="color: #1f77b4;">Título personalizado</h3>
        <p style="color: #333;">Este es un párrafo con estilos personalizados.</p>
    </div>
""", unsafe_allow_html=True)

La clave está en combinar HTML con atributos de estilo CSS dentro de las comillas triples de la función st.markdown(). El parámetro unsafe_allow_html=True le indica a Streamlit que procese el contenido como HTML real.

Aplicación de estilos globales

Una técnica especialmente útil es definir estilos CSS globales que afecten a toda la aplicación. Esto se logra insertando una etiqueta <style> con reglas CSS:

# Definir estilos globales para la aplicación
st.markdown("""
    <style>
    .main-header {
        font-size: 2.5rem;
        color: #2e86ab;
        text-align: center;
        margin-bottom: 30px;
        font-weight: bold;
    }
    
    .custom-box {
        background-color: #f8f9fa;
        border-left: 4px solid #28a745;
        padding: 15px;
        margin: 10px 0;
        border-radius: 3px;
    }
    
    .highlight-text {
        background-color: #fff3cd;
        padding: 2px 5px;
        border-radius: 3px;
        font-weight: bold;
    }
    </style>
""", unsafe_allow_html=True)

# Usar las clases CSS definidas
st.markdown('<h1 class="main-header">Mi Aplicación Personalizada</h1>', unsafe_allow_html=True)

st.markdown("""
    <div class="custom-box">
        <p>Este es un mensaje destacado con <span class="highlight-text">texto resaltado</span>.</p>
    </div>
""", unsafe_allow_html=True)

Personalización de métricas y elementos específicos

Los widgets de métricas y otros componentes pueden complementarse con elementos HTML personalizados para crear interfaces más atractivas:

# Combinar st.metric con elementos personalizados
col1, col2, col3 = st.columns(3)

with col1:
    st.markdown("""
        <div style="text-align: center; padding: 20px; background: linear-gradient(90deg, #667eea 0%, #764ba2 100%); border-radius: 10px; color: white;">
            <h3 style="margin: 0;">Ventas</h3>
            <h1 style="margin: 10px 0;">1,234</h1>
            <p style="margin: 0;">↗️ +12% vs mes anterior</p>
        </div>
    """, unsafe_allow_html=True)

with col2:
    st.markdown("""
        <div style="text-align: center; padding: 20px; background: linear-gradient(90deg, #f093fb 0%, #f5576c 100%); border-radius: 10px; color: white;">
            <h3 style="margin: 0;">Usuarios</h3>
            <h1 style="margin: 10px 0;">567</h1>
            <p style="margin: 0;">↗️ +8% vs mes anterior</p>
        </div>
    """, unsafe_allow_html=True)

with col3:
    st.markdown("""
        <div style="text-align: center; padding: 20px; background: linear-gradient(90deg, #4facfe 0%, #00f2fe 100%); border-radius: 10px; color: white;">
            <h3 style="margin: 0;">Ingresos</h3>
            <h1 style="margin: 10px 0;">€89,012</h1>
            <p style="margin: 0;">↗️ +15% vs mes anterior</p>
        </div>
    """, unsafe_allow_html=True)

Estilizado de contenido textual

El markdown enriquecido con HTML permite crear contenido más visual y estructurado:

# Crear tarjetas de información con estilos personalizados
st.markdown("""
    <div style="display: flex; gap: 20px; margin: 20px 0;">
        <div style="flex: 1; padding: 20px; background-color: #e3f2fd; border-radius: 8px; border: 1px solid #bbdefb;">
            <h4 style="color: #1976d2; margin-top: 0;">💡 Consejo</h4>
            <p style="margin-bottom: 0;">Utiliza colores consistentes en toda tu aplicación para mantener una identidad visual coherente.</p>
        </div>
        <div style="flex: 1; padding: 20px; background-color: #f3e5f5; border-radius: 8px; border: 1px solid #ce93d8;">
            <h4 style="color: #7b1fa2; margin-top: 0;">⚠️ Importante</h4>
            <p style="margin-bottom: 0;">Recuerda que el parámetro unsafe_allow_html debe usarse con precaución en aplicaciones de producción.</p>
        </div>
    </div>
""", unsafe_allow_html=True)

Creación de elementos interactivos visuales

Aunque st.markdown() no proporciona interactividad real, permite crear elementos visuales que simulan botones o enlaces:

# Crear elementos que parecen botones personalizados
st.markdown("""
    <div style="display: flex; gap: 10px; justify-content: center; margin: 30px 0;">
        <div style="padding: 10px 20px; background-color: #4CAF50; color: white; border-radius: 5px; text-align: center; cursor: pointer;">
            ✅ Completado
        </div>
        <div style="padding: 10px 20px; background-color: #ff9800; color: white; border-radius: 5px; text-align: center; cursor: pointer;">
            ⏳ En progreso
        </div>
        <div style="padding: 10px 20px; background-color: #f44336; color: white; border-radius: 5px; text-align: center; cursor: pointer;">
            ❌ Pendiente
        </div>
    </div>
""", unsafe_allow_html=True)

Consideraciones importantes

El uso de unsafe_allow_html=True requiere especial atención a la seguridad, especialmente cuando se maneja contenido dinámico o entrada de usuarios. Esta funcionalidad debe utilizarse principalmente para estilos estáticos y elementos de diseño controlados.

La compatibilidad entre navegadores puede variar ligeramente, por lo que es recomendable probar los estilos personalizados en diferentes navegadores para garantizar una experiencia consistente. Además, mantener un equilibrio entre personalización y rendimiento es crucial, evitando CSS excesivamente complejo que pueda ralentizar la carga de la aplicación.

Configuración de colores, fuentes y apariencia general

Más allá de la personalización específica con CSS, Streamlit ofrece mecanismos integrados para configurar la apariencia global de las aplicaciones. La función st.set_page_config() es el punto de entrada principal para establecer configuraciones que afectan toda la aplicación de manera sistemática.

Configuración básica de página

La función st.set_page_config() debe ser la primera llamada de Streamlit en cualquier script y permite establecer parámetros fundamentales de apariencia:

import streamlit as st

# Configuración básica de la página (debe ir al inicio del script)
st.set_page_config(
    page_title="Mi Dashboard",
    page_icon="📊",
    layout="wide",
    initial_sidebar_state="expanded"
)

El parámetro layout determina cómo se distribuye el contenido en la pantalla. La opción "wide" aprovecha todo el ancho disponible del navegador, mientras que "centered" mantiene el contenido en una columna centrada más estrecha.

Control del tema visual

Streamlit incluye soporte nativo para temas claros y oscuros que se pueden configurar a través del parámetro initial_sidebar_state y mediante configuración del archivo de configuración:

# Configuración avanzada de página con tema
st.set_page_config(
    page_title="Aplicación Moderna",
    page_icon="🚀",
    layout="wide",
    initial_sidebar_state="collapsed",
    menu_items={
        'Get Help': 'https://www.extremelycoolapp.com/help',
        'Report a bug': 'https://www.extremelycoolapp.com/bug',
        'About': "Esta es una aplicación desarrollada con Streamlit"
    }
)

Personalización de colores mediante CSS variables

Una aproximación profesional para gestionar colores consiste en definir variables CSS que mantengan consistencia en toda la aplicación:

# Definir paleta de colores personalizada
st.markdown("""
    <style>
    :root {
        --primary-color: #1f77b4;
        --secondary-color: #ff7f0e;
        --success-color: #2ca02c;
        --warning-color: #d62728;
        --background-color: #f8f9fa;
        --text-color: #212529;
        --border-color: #dee2e6;
    }
    
    .stApp {
        background-color: var(--background-color);
        color: var(--text-color);
    }
    
    .main-title {
        color: var(--primary-color);
        font-size: 2.8rem;
        font-weight: 700;
        text-align: center;
        margin-bottom: 2rem;
    }
    
    .section-header {
        color: var(--secondary-color);
        font-size: 1.5rem;
        font-weight: 600;
        border-bottom: 2px solid var(--border-color);
        padding-bottom: 0.5rem;
        margin-bottom: 1rem;
    }
    </style>
""", unsafe_allow_html=True)

# Aplicar los estilos definidos
st.markdown('<h1 class="main-title">Dashboard de Ventas 2024</h1>', unsafe_allow_html=True)
st.markdown('<h2 class="section-header">Métricas Principales</h2>', unsafe_allow_html=True)

Configuración tipográfica avanzada

La tipografía juega un papel fundamental en la legibilidad y estética de las aplicaciones. Streamlit permite personalizar fuentes mediante reglas CSS:

# Configuración de fuentes personalizadas
st.markdown("""
    <style>
    @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
    
    html, body, [class*="css"] {
        font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
    }
    
    .custom-font-light {
        font-family: 'Inter', sans-serif;
        font-weight: 300;
        font-size: 1.1rem;
        line-height: 1.6;
        color: #495057;
    }
    
    .custom-font-medium {
        font-family: 'Inter', sans-serif;
        font-weight: 500;
        font-size: 1.2rem;
        color: #212529;
    }
    
    .custom-font-bold {
        font-family: 'Inter', sans-serif;
        font-weight: 700;
        font-size: 1.4rem;
        color: #1f77b4;
    }
    </style>
""", unsafe_allow_html=True)

# Ejemplo de uso de las tipografías personalizadas
st.markdown('<p class="custom-font-light">Este es un texto con peso ligero ideal para párrafos largos y contenido descriptivo.</p>', unsafe_allow_html=True)

st.markdown('<p class="custom-font-medium">Texto con peso medio perfecto para subtítulos y contenido destacado.</p>', unsafe_allow_html=True)

st.markdown('<p class="custom-font-bold">Texto en negrita para títulos y elementos importantes.</p>', unsafe_allow_html=True)

Esquemas de color adaptativos

Para crear aplicaciones que funcionen bien tanto en modo claro como oscuro, es útil implementar esquemas de color adaptativos:

# Esquema de colores adaptativo
st.markdown("""
    <style>
    /* Tema claro (por defecto) */
    .adaptive-container {
        background-color: #ffffff;
        color: #333333;
        border: 1px solid #e0e0e0;
        padding: 20px;
        border-radius: 8px;
        margin: 10px 0;
        transition: all 0.3s ease;
    }
    
    .adaptive-accent {
        background-color: #f0f2f6;
        color: #1f77b4;
        padding: 10px 15px;
        border-radius: 5px;
        border-left: 4px solid #1f77b4;
    }
    
    /* Adaptación para temas oscuros */
    @media (prefers-color-scheme: dark) {
        .adaptive-container {
            background-color: #1e1e1e;
            color: #e0e0e0;
            border-color: #404040;
        }
        
        .adaptive-accent {
            background-color: #2a2a2a;
            color: #4dabf7;
            border-left-color: #4dabf7;
        }
    }
    </style>
""", unsafe_allow_html=True)

st.markdown("""
    <div class="adaptive-container">
        <h3>Contenido Adaptativo</h3>
        <p>Este contenedor se adapta automáticamente al tema del sistema operativo del usuario.</p>
        <div class="adaptive-accent">
            <strong>Nota:</strong> Los colores cambian según las preferencias del sistema.
        </div>
    </div>
""", unsafe_allow_html=True)

Configuración del sidebar y elementos de navegación

El sidebar y otros elementos de navegación pueden personalizarse para mantener coherencia visual:

# Personalización del sidebar
st.markdown("""
    <style>
    .css-1d391kg {  /* Selector del sidebar */
        background-color: #f8f9fa;
        border-right: 2px solid #dee2e6;
    }
    
    .sidebar-title {
        color: #495057;
        font-weight: 600;
        font-size: 1.3rem;
        text-align: center;
        padding: 1rem 0;
        border-bottom: 1px solid #dee2e6;
        margin-bottom: 1rem;
    }
    
    .sidebar-section {
        background-color: #ffffff;
        padding: 15px;
        border-radius: 8px;
        margin-bottom: 15px;
        box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    }
    </style>
""", unsafe_allow_html=True)

# Configurar contenido del sidebar con estilos personalizados
with st.sidebar:
    st.markdown('<h2 class="sidebar-title">Panel de Control</h2>', unsafe_allow_html=True)
    
    st.markdown("""
        <div class="sidebar-section">
            <h4 style="color: #6c757d; margin-bottom: 10px;">Configuración</h4>
            <p style="font-size: 0.9rem; color: #6c757d;">Ajusta los parámetros de visualización</p>
        </div>
    """, unsafe_allow_html=True)

Optimización de la apariencia responsive

Para garantizar que la aplicación se vea bien en diferentes tamaños de pantalla, es importante implementar reglas CSS responsivas:

# CSS responsive para diferentes dispositivos
st.markdown("""
    <style>
    .responsive-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
        gap: 20px;
        margin: 20px 0;
    }
    
    .responsive-card {
        background-color: #ffffff;
        padding: 20px;
        border-radius: 10px;
        box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
        border-left: 4px solid #1f77b4;
    }
    
    /* Ajustes para tablets */
    @media (max-width: 768px) {
        .responsive-grid {
            grid-template-columns: 1fr;
            gap: 15px;
        }
        
        .responsive-card {
            padding: 15px;
        }
    }
    
    /* Ajustes para móviles */
    @media (max-width: 480px) {
        .responsive-card {
            padding: 12px;
            margin: 10px 0;
        }
    }
    </style>
""", unsafe_allow_html=True)

# Ejemplo de uso del grid responsive
st.markdown("""
    <div class="responsive-grid">
        <div class="responsive-card">
            <h4>Métrica 1</h4>
            <p>Información que se adapta al tamaño de pantalla</p>
        </div>
        <div class="responsive-card">
            <h4>Métrica 2</h4>
            <p>Contenido optimizado para diferentes dispositivos</p>
        </div>
        <div class="responsive-card">
            <h4>Métrica 3</h4>
            <p>Diseño que funciona en móviles y escritorio</p>
        </div>
    </div>
""", unsafe_allow_html=True)

La consistencia visual es clave para crear aplicaciones profesionales. Establecer un sistema de diseño coherente desde el inicio, con colores, tipografías y espaciado definidos, facilita el mantenimiento y mejora significativamente la experiencia del usuario.

Fuentes y referencias

Documentación oficial y recursos externos para profundizar en Streamlit

Documentación oficial de Streamlit
Alan Sastre - Autor del tutorial

Alan Sastre

Ingeniero de Software y formador, CEO en CertiDevs

Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Streamlit es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.

Más tutoriales de Streamlit

Explora más contenido relacionado con Streamlit y continúa aprendiendo con nuestros tutoriales gratuitos.

Aprendizajes de esta lección

  • Comprender el uso de st.markdown() para incluir HTML y CSS personalizados en Streamlit.
  • Aprender a definir estilos globales y específicos para componentes visuales.
  • Configurar la apariencia general de la aplicación con st.set_page_config().
  • Implementar esquemas de color adaptativos para modos claro y oscuro.
  • Aplicar técnicas de diseño responsive y personalización del sidebar para una experiencia coherente.