During my time as a consultant, I often had to adapt my CV to the role to be filled in the client's company.
My consultancy provided a Word template with a beautiful layout that constantly got into my way: Inexplicable spaces, design elements that suddenly shifted without any identifiable reason and other appalling challenges that cost time to correct.
React and CSS
A resume is usually a one or two page long document that describes a person's professional history, their education and qualifications.
When it comes to formatting, Google lists the following basics:
- Simple and consistent design, font, sizing, and spacing
- Use of black or dark, readable ink
- Exported as a PDF
Consistency can easily be achieved with reusable components that are all based on the same styling rule-set. Instead of copy-pasting the same paragraphs, React components can separate content and design and even apply conditional logic based on the input.
The resume can also be easily localized to export it to different languages / target different markets (e.g. international vs. domestic).
CSS on the other hand provides full control of styling the printable page and its components. It's the technology every frontend/fullstack developer is familiar with and therefore significantly flattens the learning curve.
A small Create React App project comes with automatic previews / live reload out of the box, so that every change is presented immediately.
In the end the resume can be exported to PDF by printing to PDF in the browser.
@media print
CSS provides a media query to adjust the style when printing a document:
This is the recommended way to remove elements from a central code block that should be removed for printing such as a navigation bar, paddings, margins and other stylings.
@page
@page
modifies some page specific CSS rules (margin, size, page orientation, ...) and supports pseudo classes, such as :first
to only target the first page.
It's very limited and not fully supported though (see MDN):
You can't change all CSS properties with @page. You can only change the margins, orphans, widows, and page breaks of the document. Attempts to change any other CSS properties will be ignored.
The following CSS code sets the page size to the normed DINA4 and removes all margins and padding per page. This is different from using a @media print
query, which applies to the whole document, potentially spanning across multiple pages:
Example
The actual React app displays a single page that is exactly the size of a standardized DINA4 page. It serves as a live preview of what the printed page would look like.
There are some elements that are repeated several times on this page, such as each element under "Education", "Experience" as well as each element under "Contacts" or even the icons in the "Tech Stack" category.
Education Component
For example, an "Education" component is defined as follows:
It abstracts all the boilerplate code required to design the section, allowing you to focus on the data / information that needs to be presented.
(Side note: In this case I avoided handling date
props by passing the timeframe as a simple string. A date
prop would provide more programmatic control though.)
In the end, the implementation for the component could look something like this:
The className
props only need to be changed once in order to consistently change the styling across all "Education" items.
Print Preview
Once the print preview is open in the browser, it is easy to see that it is an exact copy of the preview displayed in the React app:
Conclusion
Although it requires some initial investment in setting up the React app, it pays off to implement the resume in React in the long run as it's very easy to achieve the pixel perfect resume style you may be thinking of.