Ionic es un framework muy completo que te ofrece varios componentes y la flexibilidad de cambiarles el color con un simple atributo. ¿Pero que pasa cuando creas tu propio componente y quieres tener la misma flexibilidad con los colores?

Pues que puedes hacerlo. Sin problema. Lo único que necesitas es saber un poquito de SaSS y hoy te enseño cuanto necesitas 😉

Mapa de colores de Ionic

Empecemos por el principio. Ionic dispone de una serie de colores predefinidos ( y modificables por tu parte), para cambiar de forma rápida el diseño de sus componentes.

Por defecto el mapa de colores de Ionic, la variable $colors de SaSS, tiene los colores:

  • light
  • default
  • secondary
  • danger
  • dark

Para utilizar estos colores, solo tienes que añadirle el atributo color a cualquier componente de Ionic, junto con el nombre del color.

Así pues, el siguiente código:

<button ion-button block color="light">Light</button>
<button ion-button block >Default</button>
<button ion-button block color="secondary">Secondary</button>
<button ion-button block color="danger">Danger</button>
<button ion-button block color="dark">Dark</button>

Generaría los botones que puedes ver a continuación:

Ionic button colors

Ejemplo de partida

A lo largo de todo este artículo, utilizaré un componente custom muy sencillo: una barra de progreso.

Sin entrar en mucho detalle sobre cómo está hecha esta barra de progreso, te diré que se utiliza del siguiente modo:

<!-- some ionic view where I want to display a progress bar -->

<ion-content padding>
  <app-progress-bar progress="50"></app-progress-bar>
</ion-content>

Y esto mostraría un progreso del 50%, así:

progress bar

Si quieres aprender a hacer componentes como éste o más complejos, dale un vistazo a mi curso «Componentes en Angular – nivel PRO».

El componente app-progress-bar es realmente simple. Su template consta de un div, de forma que el componente en sí es el que crea el marco, mientras que el div de dentro se corresponde con el progreso.

Los estilos serían estos:
progress-bar.component.scss:

app-progress-bar{
    display: block;
    overflow: hidden;
    height: 20px;
    width: 100%;
    background-color: white;
    border: 1px solid #333;

    div{
       background-color: #333;
       height: 100%;
    }
}

Usando los colores de Ionic desde SaSS

Si te fijas, ahora mismo la barra de progreso está utilizando un color hardcodeado, el #333, que viene a ser un gris oscuro.

Como paso previo a generalizar el diseño para todo el mapa de colores de Ionic, voy a empezar con un solo color.

Pongamos que quiero que al utilizar el atributo color='danger', el color de la barra de progreso coincida con el color «danger».

Para ello, solo tengo que añadir este fragmento a los estilos de mi componente:

app-progress-bar{
    /* ...previous stuff... */

    &[color="danger"]{
        border: 1px solid color($colors, danger);
        div{
            background-color: color($colors, danger);
        }
    }
}

Es decir, dentro de la progress-bar, si además tiene el atributo color con el valor danger, le cambio el color del borde para poner el color danger. Además, en su div interior, hago exáctamente lo mismo con el color de fondo.

Nota: Ionic proporciona una función para obtener un color concreto de su mapa de colores $colors, eso es lo que uso con color($colors, danger).

Ahora, si actualizo mi vista con una barra de progreso en este color:

<!-- some ionic view where I want to display a progress bar -->
<ion-content padding>
  <app-progress-bar progress="50"></app-progress-bar>
  <app-progress-bar progress="80" color="danger"></app-progress-bar>
</ion-content>

Veo como efectivamente los estilos hacen su trabajo y consigo el color deseado.

ionic progress bar with color attribute

Generalizando los estilos de tu componente con los colores de Ionic

Ya tengo casi todo el trabajo, pero me falta generalizarlo para todos los colores de $colors.

Como no quiero picar todos los colores a mano y además eso no sería escalable si añado nuevos colores, necesito usar un bucle de SaSS.

La estructura básica de un bucle SaSS es la siguiente:

//sass bucle
@each $content in $myArray{
    .myClass#{$content}{
        //do something here...
    }
}

El código anterior recorre el array $myArray y para cada elemento, deposita su contenido en $content, de forma que puedes usar su valor (con la sintaxis #{$content}) para automatizar la creación de estilos, o lo que quieras.

El caso de $colors es un poco más complejo por que no es un array, sino un mapa de elementos (clave-valor). Por eso, el bucle para añadir estilos de colores a mi barra de progreso quedaría así:

app-progress-bar{
    /* ...previous stuff...*/

    @each $name, $color in $colors{
        &[color='#{$name}']{
            border: 1px solid #{$color};
            div{
                background-color: #{$color};
            }            
        }
    } 
}

Fíjate como en ${name} obtengo la clave del color (danger, light, etc), mientras que en ${color} obtengo su valor (#488aff, etc).

Con apenas estas 5 líneas en los estilos del componente, puedo usar ya todos los colores del mapa de colores de Ionic. ¡Fíjate!

<!-- some ionic view where I want to display a progress bar -->
<ion-content padding>
  <app-progress-bar progress="20"></app-progress-bar>
  <app-progress-bar progress="30" color="primary"></app-progress-bar>
  <app-progress-bar progress="40" color="secondary"></app-progress-bar>
  <app-progress-bar progress="50" color="danger"></app-progress-bar>
  <app-progress-bar progress="60" color="light"></app-progress-bar>
  <app-progress-bar progress="70" color="dark"></app-progress-bar>
</ion-content>

Aquí tienes el resultado:

Ionic colored progress bars

Bonus track

Esto ya no tiene que ver con los colores, pero no puedo resistirme, estas barras de progreso son muy feas. ¿Podemos hacerlas mas bonitas con los bordes redondeados? ¿Sí? ¡GRACIAS!

Añado un par de propiedades en base al atributo rounded y los estilos finales del componente quedan así:

app-progress-bar{
    display: block;
    overflow: hidden;
    height: 20px;
    width: 100%;
    background-color: white;
    border: 1px solid #333;

    div{
       background-color: #333;
       height: 100%;
    }

    @each $name, $color in $colors{
        &[color='#{$name}']{
            border: 1px solid #{$color};
            div{
                background-color: #{$color};
                }            
        }
    } 

     &[rounded]{
        border-radius: 10px;
        div{
            border-radius: 10px 0px 0px 10px;
        }
    }
}

Gracias a la potencia de SaSS, con tan pocas líneas he conseguido generar los estilos para poder hacer todo esto:

<ion-content padding>

  <h3>Basic progress bars</h3>
  <app-progress-bar progress="20"></app-progress-bar>
  <app-progress-bar progress="30" color="primary"></app-progress-bar>
  <app-progress-bar progress="40" color="secondary"></app-progress-bar>
  <app-progress-bar progress="50" color="danger"></app-progress-bar>
  <app-progress-bar progress="60" color="light"></app-progress-bar>
  <app-progress-bar progress="70" color="dark"></app-progress-bar>

  <h3>Rounded progress bars</h3>
  <app-progress-bar progress="20" rounded></app-progress-bar>
  <app-progress-bar progress="30" rounded color="primary"></app-progress-bar>
  <app-progress-bar progress="40" rounded color="secondary"></app-progress-bar>
  <app-progress-bar progress="50" rounded color="danger"></app-progress-bar>
  <app-progress-bar progress="60" rounded color="light"></app-progress-bar>
  <app-progress-bar progress="70" rounded color="dark"></app-progress-bar>

</ion-content>

Y generar el siguiente resultado:

Ionic colored rounded progress bars

¿Quieres ver en realidad todo el código CSS que ha generado este SaSS tan breve? Ahí lo tienes:

app-progress-bar {
  display: block;
  overflow: hidden;
  height: 20px;
  width: 100%;
  background-color: white;
  border: 1px solid #333;
}

app-progress-bar div {
  background-color: #333;
  height: 100%;
}

app-progress-bar[color='primary'] {
  border: 1px solid #488aff;
}

app-progress-bar[color='primary'] div {
  background-color: #488aff;
}

app-progress-bar[color='secondary'] {
  border: 1px solid #32db64;
}

app-progress-bar[color='secondary'] div {
  background-color: #32db64;
}

app-progress-bar[color='danger'] {
  border: 1px solid #f53d3d;
}

app-progress-bar[color='danger'] div {
  background-color: #f53d3d;
}

app-progress-bar[color='light'] {
  border: 1px solid #f4f4f4;
}

app-progress-bar[color='light'] div {
  background-color: #f4f4f4;
}

app-progress-bar[color='dark'] {
  border: 1px solid #222;
}

app-progress-bar[color='dark'] div {
  background-color: #222;
}

app-progress-bar[rounded] {
  border-radius: 10px;
}

app-progress-bar[rounded] div {
  border-radius: 10px 0px 0px 10px;
}

Conclusiones

Has visto como, apoyándose en SaSS, Ionic proporciona una forma muy sencilla y flexible para proporcionar toda una gama cromática a tus componentes custom, de la misma forma que los componentes propios del framework. De hecho, la metodología que plantean no aplica solo a Ionic, sino que sirve para cualquier proyecto que utilice SaSS.

En todo caso, espero que este ejemplo te sirva para mejorar el diseño de tus componentes en el futuro.

Un abrazo

Si te ha gustado el artículo, no te lo quedes para ti ¡compártelo! 😉