How I effectively utilized CSS flex and pseudo-classes to create a dynamic layout structure (while avoiding inline styles)
In my entire web-dev career I have actively tried to avoid using inline styles unless ABSOLUTELY necessary (which is never! ok, unless you need a quick fix and it’s not for production).
Here in my example today I will demonstrate an effective method to utilize CSS flex and pseudo-classes to dynamically create a simple layout structure.

HTML
For simplicity’s sake we will use pure HTML here.
<div className="projects">
/*--- First Listing ---*/
<div className="project-listing">
<div className="project-headings">
<div className="numeric">1</div>
<h3 className="project-title">Frontline Contech App</h3>
</div>
<div className="project-summary">
Role: Design, UI/UX, Front-End Development <br />
Tools: React.js, Javascript, HTML, CSS<br />
Link:
<a href="https://app.frontline-optimizer.com/#/login" target="_blank" rel="noreferrer">
/app.frontlinec.com
</a>
<br /> <br />
Conceptualized, designed, and developed the entire UI and UX aspects of the web application, ensuring an intuitive and seamless user experience.
</div>
<img className="project-image" src={imageURL} alt="Frontline Contech App Login Page" />
<img className="project-image" src={imageURL} alt="Frontline Contech App Landing Page" />
</div>
/*--- Second Listing ---*/
<div className="project-listing">
<div className="project-headings">
<div className="numeric">2</div>
<h3 className="project-title">Merquri.io</h3>
</div>
<div className="project-summary">
Role: UI/UX, Front-End Development<br />
Tools: React.js<br />
Link:
<a href="https://merquri.io/" target="_blank" rel="noreferrer">
/merquri.io
</a>
<br /> <br />
Translated design to code and developed the company's corporate site alongside team mates.
</div>
<img className="project-image" src={imageURL} alt="Merquri Page" />
</div>
/*--- Third Listing ---*/
<div className="project-listing">
<div className="project-headings">
<div className="numeric">3</div>
<h3 className="project-title">GIF Search</h3>
</div>
<div className="project-summary">
Role: Front-End Development <br />
Tools: React.js, GIPHY API <br />
Link:
<a href="https://github.com/rachellesg/gif-search" target="_blank" rel="noreferrer">
/gif-search
</a>
<br /> <br />
Hobby side project: GIF search made with Reactjs and GIPHY API.
</div>
<img className="project-image" src={imageURL} alt="GIF Search Page" />
</div>
</div>
In the HTML example above, notice the subtle yet significant differences in the appearance of the three code blocks when rendered in a browser.
In the first project listing, the width spans 100%, accommodating two images placed side by side. In contrast, the second and third project listings occupy 50% width each, featuring only one image per listing.
CSS
.projects {
display: flex;
flex-wrap: wrap; // ensures flex items will go into multiple lines if they don't fit
justify-content: space-between; // gives equal spacing in between 2 listings
padding: 30px 0; // gives padding top and bottom
}
.project-listing {
margin: 25px 0;
width: 48%; // all items will default take up half width
.project-image {
width: 100%;
margin: 15px 0;
}
}
/*
using the first-of-type pseudo class here to change the
first element with the class name project-listing
*/
.project-listing:first-of-type {
width: 100% !important;
.project-image {
width: 50%;
}
}
This approach can be expanded by utilizing other pseudo-classes, such as nth-of-type(X), to scale the styling and targeting of specific elements if required.
Inline styling was avoided in the code to improve readability, reusability, and maintainability. Instead, external stylesheets and CSS classes were utilized.
This separation of content and presentation promotes a modular approach, making it easier to apply consistent styles and collaborate with a development team.
By adhering to these principles, the codebase became cleaner, more scalable, and efficient to update and maintain.
Further expansion in React.js:
Let’s say you have 100 project listings instead of 3. Do we copy and paste all 100? The answer is no.
You can simply place your data in an Object and map it over.
<div className="projects">
{portfolioProjects.map((item, index) => {
const projectIndex = index + 1
const {
projectName,
role,
description,
link,
linkName,
imageURL,
imageAltText,
tools,
} = item
return (
<div key={projectName} className="project-listing">
<div className="project-headings">
<div className="numeric">{projectIndex}</div>
<h3 className="project-title">{projectName}</h3>
</div>
<div className="project-summary">
Role: {role} <br />
Tools: {tools} <br />
Link:
<a href={link} target="_blank" rel="noreferrer">
{linkName}
</a>
<br /> <br />
{description}
</div>
{imageURL.length === 2 ? imageURL.map((i) => <img className="project-image" src={i} alt={imageAltText} />) : <img className="project-image" src={imageURL} alt={imageAltText} />}
</div>
)
})}
</div>
Easy!