A profile card component (React)
This React Profile card is based on this Frontend Mentor visual design. My initial submission used html/css but has since been refactored into a React component using Styled Components.
This project has a dual purpose—to serve as a basic React component for a Frontend Mentor challenge and to serve as an example of a React component for the challenge.
This component uses Styled Components, PropTypes for type checking, and Airbnb's ESLint config.
First clone the repository.
To install dependencies, you'll need npm (distributed with Node.js) or yarn.
cd <project directory>
npm install
In the project directory, you can run the app with:
npm start
Runs the app in the development mode.
Open http://localhost:3000 to view it in the browser.
The page will reload if you make edits.
You will also see any lint errors in the console.
There are a variety of ways to style React components. This project uses Styled Components. Styled Components allow you to build smaller, styled components using plain CSS ("Every style is a component"). Josh Comeau's The styled-components Happy Path is an excellent introduction and the official docs are wonderful as well.
The ProfileCard component's CSS styles are found in ProfileCard.elements.js and App.js, but the React app also has styles used to center component (app.elements.js).
- App.js
- app.elements.js
- ProfileCard.elements.js
In App.js, a GlobalStyle is created with a simple CSS reset, CSS variables, and a background only used when displaying the component within this app. For a bigger project, it would be better to define the GlobalStyle in another file.
const GlobalStyle = createGlobalStyle`
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
:root {
--dark-cyan: hsl(185, 75%, 39%);
--text-color: hsl(229, 23%, 23%);
--dark-grayish-blue: hsl(227, 10%, 46%);
--text-color-light: hsl(0, 0%, 59%);
--stats-border: #E8E9EC;
}
body {
background: url(bg-pattern-top.svg) -250px -530px no-repeat,
url(bg-pattern-bottom.svg) 650px 400px no-repeat,
var(--dark-cyan);
padding: 1.5rem;
font-family: 'Kumbh Sans', sans-serif;
}
`;
The GlobalStyle is a special type of StyledComponent that does not accept children. When placed at the the top of the React tree, "the global styles will be injected when the component is 'rendered'." docs
In the App() component below <GlobalStyle />
, the standard component <ProfileCard />
is surrounded by a StyledComponent called <StyledWrapper>
. The wrapper is simply a <div>
with CSS styles defined in app.elements.js. The wrapper is used to center the component.
function App() {
return (
<>
<GlobalStyle />
<StyledWrapper>
<ProfileCard profile={sampleProfile} />
</StyledWrapper>
</>
);
}
This file contains all of the component's styles (minus CSS variables): <div>
s, <p>
s, <span>
s, and an <img>
.
Each styled HTML element is given a component name and then defined with regular CSS. You can even include media queries like in the ProfileStats <div>
.
Try experimenting with the CSS rules. When you save, the page should automatically refresh with your changes.
import styled from "styled-components";
export const ProfileCardWrapper = styled.div`
min-width: 10.375rem; /* clamp wasn't respecting it's min-width */
width: clamp(10.375rem, 100%, 21.875rem);
background: #fff;
box-shadow: 0 3.125rem 6.25rem -1.25rem rgba(8, 70, 94, 0.504835);
border-radius: 0.9375rem;
font-family: "Kumbh Sans", sans-serif;
`;
…
export const ProfileStats = styled.div`
width: 100%;
margin-bottom: 1.5rem;
display: grid;
grid-template-columns: repeat(3, auto);
grid-template-rows: repeat(2);
row-gap: 0.5625rem;
padding-top: 1.5rem;
border-width: 0.0625rem 0px 0px 0px;
border-style: solid;
border-color: var(--stats-border);
@media only screen and (max-width: 268px) {
grid-template-columns: repeat(1, auto);
row-gap: 1rem;
}
`;
export const StatWrapper = styled.div`
display: flex;
flex-direction: column;
`;
export const Stat = styled.span`
font-size: 1.125rem;
font-weight: 700;
color: var(--text-color);
text-align: center;
margin-bottom: 0.5625rem;
`;
export const Label = styled.span`
font-size: 0.625rem;
letter-spacing: 0.09375rem;
color: var(--text-color-light);
text-align: center;
`;
If you are a member of the Frontend Mentor community, you can comment here.
Open an issue, submit PRs, or ping me on twitter @aaron_stroud.
MIT © Aaron Stroud