Mobile First - React Styled-Components - CSS Grid
Norberto Krucheski
Posted on September 2, 2021
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:
Para comenzar creamos un proyecto de react y luego instalamos styled-components.
npm create-react-app first-mobile
npm install --save styled-components
Ejecutamos nuestro proyecto:
npm start
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.
Editamos los archivos index.js y App.js para que no nos de errores, deben de quedar así:
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;
}
Importamos este componente en el nivel mas alto de la app, en nuestro caso en App.js, debe quedar así:
Ahora vamos escribir los componentes para maquetar nuestro sitio y se vea de esta forma:
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.
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;`
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;
Si vemos nuestro proyecto actual, no tiene mucho estilo que digamos, solo sigue el orden jerarquizo de la etiquetas HTML.
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);
`
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
`
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
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*/
`
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.
Posted on September 2, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.