DEV Community

Cover image for Mobile First - React Styled-Components - CSS Grid
Norberto Krucheski
Norberto Krucheski

Posted on

Mobile First - React Styled-Components - CSS Grid

A la hora de comenzar un proyecto web, ya sea una app o un sitio, si el mismo debe ser responsive, generalmente puede surgir la pregunta; ¿en que resolución comenzar el proyecto?.

Como su nombre lo indica mobile first «los móviles primero», resume perfectamente esta filosofía de diseño.

Se refiere a un modo de diseñar que tenga en cuenta, en primera instancia, un dispositivo móvil.

A la hora de diseñar, podemos optar por usar frameworks como; Boostrap, Tailwind (el mejor 😁), o hacerlo de forma manual.

En esta guía quiero enseñarte una forma sencilla de encarar el diseño utilizando CSS Grid, Areas y Templates, una vez que definimos la maqueta de nuestro sitio, se puede hacer un diseño responsive de forma muy sencilla.

Queremos lograr una diseño responsive como este:

Diseño Responsive

Para comenzar creamos un proyecto de react y luego instalamos styled-components.

npm create-react-app first-mobile
Enter fullscreen mode Exit fullscreen mode
npm install --save styled-components
Enter fullscreen mode Exit fullscreen mode

Ejecutamos nuestro proyecto:

npm start
Enter fullscreen mode Exit fullscreen mode

Lo primero que vamos hacer es eliminar los archivos que no utilizamos:

  • App.css
  • App.test.js
  • logo.svg
  • reportWebVitals.js

NOTA: El archivo index.css trae unos estilos por defecto para react, estos los utilizaremos con styled-components y luego borraremos el archivo.

repositorio react Limpio

Editamos los archivos index.js y App.js para que no nos de errores, deben de quedar así:

App.js
repositorio react Limpio
index.js
repositorio react Limpio

Temas que vamos a ver:

React con Styled-Components
CSS Grid + Grid Area

React con Styled-Components

Este módulo nos permite estilizar nuestros componentes, se considera buenas practicas definir a que componente le corresponde que estilo.

Lo mejor de styled-componentes, es que nos permite escribir nuestro CSS de toda la vida, pero también es posible combinarlo con framworks como Tailwind.

Otra ventaja de styled-componentes; es que nos genera clases automáticas, y es imposible que nuestras clases entren en conflicto entre ellas.

Vamos a comenzar con escribir los estilos globales para toda la app (lo que teníamos en index.css).

Para hacerlo de una forma mas ordenada, crearemos dentro de la carpeta src, una carpeta llamada styles.

Creamos un archivo llamado globalStyles.js, importamos createGlobalStyle para crear estilos globales.

Creamos un componente llamado GlobalStyle, donde entre bastics (esa comillas simples invertidas) pegamos el cógido de index.css (luego podemos borrar el index.css).

import {createGlobalStyle} from 'styled-components'

export const GlobalStyle = createGlobalStyle`

//Estilos por defecto que trae React
body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
    'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
    sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

code {
  font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
    monospace;
}
Enter fullscreen mode Exit fullscreen mode

Importamos este componente en el nivel mas alto de la app, en nuestro caso en App.js, debe quedar así:
Global Style React Styled Components

Ahora vamos escribir los componentes para maquetar nuestro sitio y se vea de esta forma:

React Styled Components

Pero vamos hacerlo directamente con styled-components.
Dentro de la carpeta styles, creamos otro archivos llamados model.js, (la idea es modelar el sitio).

Importamos styled de styled-componentes, y generamos nuestro primer componente estilizado.

Primer componente styled-componentes

Como se puede ver, se crea un componente (Mayúscula), y de styled utilizamos un div.

Styled = contiene todas las etiquetas HTML.

Vamos a proceder a crear el resto de componentes.

import styled from 'styled-components'

export const Container = styled.div`
width: 90%;
max-width: 1000px;
margin:20px auto;
`

export const Header = styled.header`
background: blue;
color: #fff;
`

export const Main = styled.main`
padding-left: 2%;
`

export const Sidebar = styled.aside`
background: orange;
min-height: 100px;
`

export const Widget = styled.div`

background: orchid;
height: 100px;
`

export const Footer = styled.footer`
padding: 20px;
background: maroon;
color: #fff;`
Enter fullscreen mode Exit fullscreen mode

Ahora vamos a importar nuestros componentes en App.js y le vamos asignar una className adicional que usaremos en un futuro.

import { GlobalStyle } from "./styles/globalStyles";
import { Container, Header, Main, Sidebar, Widget, Footer } from "./styles/model";

function App() {
  return (
    <>
      <GlobalStyle />

      <Container className="contenedor">

        <Header className="header">
          <h1>Header</h1>
        </Header>

        <Main className="contenido">
          <h2>Test</h2>
          <p>Lorem asdasd</p>
        </Main>

        <Sidebar className="sidebar">Sidebar</Sidebar>

        <Widget className="widget-1">Widget-1</Widget>
        <Widget className="widget-2">Widget-2</Widget>

        <Footer className="footer">Footer</Footer>

      </Container>

    </>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Si vemos nuestro proyecto actual, no tiene mucho estilo que digamos, solo sigue el orden jerarquizo de la etiquetas HTML.

React Styled Components

CSS Grid + Grid Area

Para trabajar en Grid, lo que necesitamos es definir una grilla en donde acomodamos nuestro diseño, muchos frameworks usan el sistema de columnas y filas para posicionar objetos en la grilla, nosotros lo haremos de forma manual. 💪

Mi idea no es explicar CSS Grid a fondo 😢 , si no mostrar la magia de Grid Area.

En nuestro ejemplo, nuestro diseño cuenta con 3 columnas, y filas automáticas según el contenido.

Vamos a actualizar el código del componente Container, y automáticamente ya tendremos grid.

export const Container = styled.div`
width: 90%;
max-width: 1000px;
margin:20px auto;
display: grid;
grid-gap: 20px;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(4, auto);
`
Enter fullscreen mode Exit fullscreen mode

grid area css

Ya tenemos una grilla, pero aun no un diseño responsive que se adapte a cualquier resolución.

Es aquí donde aparece grid area. Literalmente, nos permite definir con áreas nuestros elementos HTML, a cada componente que creamos, le asignamos un área, debe quedar así:

import styled from 'styled-components'

export const Container = styled.div`
width: 90%;
max-width: 1000px;
margin:20px auto;
display: grid;
grid-gap: 20px;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(4, auto);
`

export const Header = styled.header`
background: blue;
color: #fff;
grid-area: header; //área

& > h1 {
    margin-left: 2%;
}

`

export const Main = styled.main`
padding-left: 2%;
grid-area: contenido; //área
`

export const Sidebar = styled.aside`
background: orange;
min-height: 100px;
grid-area: sidebar; //área

/*flexbox para acomodar elementos*/

display: flex;
align-items: center;
justify-content: center; //área
`

export const Widget = styled.div`

background: orchid;
height: 100px;
grid-area: ${props => props.className === "widget-1" ? "widget-1" : "widget-2"}; //área

/*flexbox para acomodar elementos*/

display: flex;
align-items: center;
justify-content: center;
`

export const Footer = styled.footer`
padding: 20px;
background: maroon;
color: #fff;
grid-area: footer; //área
`
Enter fullscreen mode Exit fullscreen mode

NOTA: En el componente Widget por medio de props, podemos asignarle un valor condicional (otra ventaja de styled components).

Una vez que ya tenemos las áreas definidas, tenemos que utilizar grid-template-area, para escribir nuestro diseño, esto lo hacemos en el archivo globalStyles.js

grid template area

Como se puede ver, nuestro tamplate, esta basado en 3 columnas (nuestra grilla), solo debemos asignar nuestros componentes al área que deseamos, siempre respetando las 3 columnas para nuestro ejemplo.

Ahora lo que resta es aplicar los diferenntes templates para las diferentes resoluciones, en nuestro caso, como estamos trabajando con la filosofía mobile-first, creamos las áreas de menor a mayor resolución.

Para esto usamos los media-queries de toda la vida en CSS.
En cada resolución, aplicamos un grid-template-area, y redibujamos nuestro diseño.

import {createGlobalStyle} from 'styled-components'

export const GlobalStyle = createGlobalStyle`

//Estilos por defecto que trae React
body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
    'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
    sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

code {
  font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
    monospace;
}


//Estilos para Grid Area

/*Grid Area First Mobile*/

/*min 640px*/
.contenedor {
grid-template-areas: "header header header"
                    "contenido contenido contenido"
                    "sidebar sidebar sidebar"
                    "widget-1 widget-1 widget-1"
                    "widget-2 widget-2 widget-2"
                    "footer footer footer"
;
}


/*min 768px*/
@media screen and (min-width: 768px){
.contenedor{
grid-template-areas:    "header header header"
                        "contenido contenido contenido"
                        "sidebar sidebar sidebar"
                        "widget-1 widget-1 widget-2"
                        "footer footer footer"
;
}    
}

/*min 1024px*/
@media screen and (min-width: 1024px){
.contenedor{
grid-template-areas:    "header header header"
                        "contenido contenido sidebar"
                        "widget-1 widget-2 sidebar"
                        "footer footer footer"
;
}

}

/*min 1280px*/
@media screen and (min-width: 1280px){
.contenedor{
grid-template-areas:    "header header header"
                        "contenido contenido sidebar"
                        "widget-1 widget-1 sidebar"
                        "widget-2 widget-2 sidebar"
                        "footer footer footer"
;
}

}

/*min 1536px*/

`
Enter fullscreen mode Exit fullscreen mode

En este caso, solo creamos la estructura de nuestro sitio, pero una vez que rellenamos con nuestro contenido, podemos alinear contenido con flexbox como se muestra en el el ejemplo, en resumen, se puede utilizar el CSS de toda la vida, o combinarlo con otros framworks.

La idea principal es armar una maqueta que sea responsive, luego el contenido de cada área, se debe trabajar por separado, pero si se combina con flexbox, o subgrid, los componentes se puede manipular sin problemas.

Repo: React-StyledComponent-CSS-GridArea

Gracias
Norberto.

Discussion (2)

Collapse
hector4like6gorillaz profile image
hector4like6gorillaz

Me ha encantado, hasta el momento desconocia que podia crear un grid desde ese punto, por lo general lo realizaba de modo manual en cada componente. Gracias desde el grupo de Facebook!!!!

Collapse
norbertok profile image
Norberto Krucheski Author

Gracias a ti por comentar.
Es un método muy cómodo y facil de hacerlo.