Skip to content

Commit

Permalink
fix: footer positioning (#60)
Browse files Browse the repository at this point in the history
* fix: automatic page count for small screens

* fix: automatic footer positioning for print

* feat: use paged.js for print layout
  • Loading branch information
cjshearer authored Jul 29, 2024
1 parent b24a61b commit 0411d2c
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 92 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# modern-hugo-resume

A responsive, minimal, print-friendly resume builder. Powered by Hugo, Tailwind CSS, Nix, and GitHub Pages.
A responsive, minimal, print-friendly resume builder. Powered by Hugo, Tailwind CSS, Paged.js, Nix, and GitHub Pages.

_Host your own resume on GitHub for free!_

Expand Down
72 changes: 31 additions & 41 deletions assets/css/modern-hugo-resume.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,20 @@
margin-right: auto;
max-width: var(--page-width);
padding: var(--page-margin);
}

main {
padding-bottom: var(--page-margin);
@media not all and (min-width: theme("screens.sm")) {
padding: theme("margin.3");
}

& > *:first-child {
margin-top: 0;
@media print {
padding: 0;
}
}

main > *:first-child {
margin-top: 0;
}

:root {
--background: theme("colors.white");
--body: theme("colors.gray.700");
Expand All @@ -29,10 +33,8 @@
--invert-body: theme("colors.gray.300");
--invert-headings: theme("colors.white");
--invert-link-hover: theme("colors.gray.100");
}

@media (prefers-color-scheme: dark) {
:root {
@media (prefers-color-scheme: dark) {
--background: var(--invert-background);
--body: var(--invert-body);
--headings: var(--invert-headings);
Expand All @@ -42,11 +44,15 @@

h1,
h2,
h3 {
h3,
h4,
h5,
h6 {
color: var(--headings);
margin-bottom: theme("margin.4");
margin-top: theme("margin.6");
line-height: 1.25;
break-after: avoid;
}

h1 {
Expand All @@ -64,6 +70,9 @@
font-weight: theme("fontWeight.semibold");
}

h4,
h5,
h6,
a,
p,
li {
Expand All @@ -75,6 +84,7 @@
ul,
ol {
margin-bottom: theme("margin.4");
break-inside: avoid;
}

ul {
Expand All @@ -96,43 +106,22 @@

a {
text-decoration-line: underline;
}

a:hover {
color: var(--link-hover);
}

footer {
width: theme("width.full");
}

@media print {
body {
padding: 0;
}

main {
padding-bottom: 0;
&:hover {
color: var(--link-hover);
}

a {
@media print {
text-decoration-line: none;
}
}

h2,
h3,
p {
break-after: avoid-page;
}

p,
ul {
break-inside: avoid-page;
}
footer {
padding-top: var(--page-margin);
position: running(footer);

footer {
position: absolute;
bottom: calc((1 - var(--page-count)) * 100%);
@media print {
padding-top: 0;
}
}
}
Expand Down Expand Up @@ -160,6 +149,7 @@
}

@page {
margin: var(--page-margin);
size: var(--page-width) var(--page-height);
@bottom-center {
content: element(footer);
}
}
51 changes: 51 additions & 0 deletions assets/js/modern-hugo-resume.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
async function initializePagedJS() {
await Promise.all([
import("https://unpkg.com/[email protected]/dist/paged.min.js"),
new Promise((resolve) => {
if (document.readyState !== "loading") resolve();
document.addEventListener("DOMContentLoaded", () => resolve());
}),
]);

// Workaround for using custom properties with @page rules. For background on why this is an
// issue, see: https://stackoverflow.com/a/44738574
const referencePage = document.createElement("div");
referencePage.style.height = "var(--page-height)";
referencePage.style.width = "var(--page-width)";
referencePage.style.margin = "var(--page-margin)";
referencePage.style.position = "absolute";
referencePage.style.top = "-9999px";
document.body.appendChild(referencePage);
const referencePageStyles = window.getComputedStyle(referencePage);
const style = document.createElement("style");
style.innerHTML = `@page {
${Object.entries({
size: `${referencePageStyles.width} ${referencePageStyles.height}`,
margin: referencePageStyles.margin,
}).reduce((acc, [key, value]) => `${acc}${key}: ${value};\n`, "")}
}`;
document.head.appendChild(style);
document.body.removeChild(referencePage);

const previewer = new PagedModule.Previewer();
await previewer.preview();
}

function showPrintPage() {
const url = new URL(window.location.href);
url.searchParams.set("print", "true");
history.pushState({}, "", url);
initializePagedJS();
}

if (new URL(window.location.href).searchParams.has("print")) {
initializePagedJS();
} else {
window.onbeforeprint = showPrintPage;
}

window.onafterprint = () => {
const url = new URL(window.location.href);
url.searchParams.delete("print");
window.location.href = url.href;
};
10 changes: 5 additions & 5 deletions exampleSite/content/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Software Developer with 3 Years of Full Stack Web and Mobile Experience

### Software Developer – Full Stack, Krumware

March 2021 to October 2023
#### March 2021 to October 2023

- Collaborated in cross-functional team following agile (scrum) methodologies
- Improved time-to-market by up to 20% with project templates
Expand All @@ -34,7 +34,7 @@ March 2021 to October 2023
- Led company transition to Golang, improving performance, type-safety, and DX
- Promoted culture of continuous improvement, code reviews, and linting

Project Highlights:
##### Project Highlights:

- Developed React app, React-Native app, Node servers for equipment manufacturer
- Created Bluetooth abstraction with data anomaly filtering, connection recovery
Expand All @@ -51,15 +51,15 @@ Project Highlights:

### Research Assistant, AI and Systems Laboratory

August 2020 to April 2021
#### August 2020 to April 2021

- Analyzed cross-platform performance behavior of deep-learning recommender system
- Reproduced results from past research on highly configurable systems
- Researched relevant works on causal inference and machine learning

### Software Developer – Intern, Velocity

June 2018 to August 2018
#### June 2018 to August 2018

- Created AWS storage primitive abstracting cloud complexity for high level orchestration
- Developed storage optimization solution for Amazon Elastic Block Storage
Expand All @@ -68,7 +68,7 @@ June 2018 to August 2018

### BS Computer Science, University of South Carolina

August 2017 to May 2021
#### August 2017 to May 2021

- Graduated _magna cum laude_ with a mathematics minor
- Achieved [Outstanding Senior Award](https://sc.edu/about/offices_and_divisions/leadership_and_service_center/awards_and_recognition/senior-awards/index.php) and the [Palmetto Fellows Scholarship](https://sc.edu/about/offices_and_divisions/financial_aid/scholarships/scholarships_for_sc_residents/palmetto_fellows/index.php)
Expand Down
57 changes: 12 additions & 45 deletions layouts/modern-hugo-resume/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,57 +38,24 @@

{{- with (templates.Defer (dict "key" "global")) -}}
{{- with resources.Get "css/modern-hugo-resume.css" -}}
{{ $opts := dict
{{
$opts := dict
"inlineImports" true
"optimize" hugo.IsProduction
}}
{{- with . | css.TailwindCSS $opts -}}
{{- if hugo.IsDevelopment -}}
<link rel="stylesheet" href="{{ .RelPermalink }}" />
{{- else -}}
{{- with . | minify | fingerprint -}}
<style>{{- .Content | safeCSS }}</style>
{{- end -}}
{{- end -}}
{{- $style := . | css.TailwindCSS $opts -}}
{{- if hugo.IsProduction -}}
{{- $style = $style | minify | fingerprint -}}
{{- end -}}
<style>{{- $style.Content | safeCSS }}</style>
{{- end -}}
{{- end -}}
{{- with resources.Get "js/modern-hugo-resume.js" -}}
{{- $defines := dict "import.meta.env.MODE" (printf `"%s"` hugo.Environment) -}}
{{- $opts := dict "format" "esm" "defines" $defines -}}
{{- $js := . | js.Build $opts -}}
<script type="module">{{- $js.Content | safeJS -}}</script>
{{- end -}}
</head>
{{ .Content }}
<script defer>
(() => {
const main = document.getElementsByTagName("main")?.[0];
const footer = document.getElementsByTagName("footer")?.[0];

if (!(footer && main)) return;

// referencePage helps calculate which page to place the footer on when printing
const referencePage = document.createElement("div");
referencePage.style.height = "var(--page-height)";
referencePage.style.margin = "var(--page-margin)";
referencePage.style.position = "absolute";
referencePage.style.top = "-9999px";
document.body.appendChild(referencePage);

// dummyFooter prevents the real footer from overlapping the main document
const dummyFooter = document.createElement("div");
dummyFooter.style.height = getComputedStyle(footer).height;

const referencePageStyles = window.getComputedStyle(referencePage);
const documentHeight =
document.body.scrollHeight - 2 * Number.parseFloat(dummyFooter.style.height);
const effectivePageHeight =
Number.parseFloat(referencePageStyles.height) -
Number.parseFloat(referencePageStyles.marginTop) -
Number.parseFloat(referencePageStyles.marginBottom);

document.documentElement.style.setProperty(
"--page-count",
Math.ceil(documentHeight / effectivePageHeight),
);

onbeforeprint = () => main.appendChild(dummyFooter);
onafterprint = () => main.removeChild(dummyFooter);
})();
</script>
</html>

0 comments on commit 0411d2c

Please sign in to comment.