CSS for PDF export works well... but header formatting does not cooperate

Greetings fellow Obsidian users.
I have the following CSS snippet to format my texts when exporting notes to PDFs:

@import "pdf-print.js";
@media print {
  @page {
    margin-top: 1.1in;
    margin-bottom: 1.3in;
  }
    h1, h2, h3, h4, h5, h6, p {
    font-family: "Times New Roman", Times, serif;
  }
  h2, h3, h4, h5, h6{ 
    text-align: center;
  }
  h1 {
    font-size: 24px;
    text-align: center;
    page-break-before: always;
  }
  p {
    font-size: 14px;
    text-align: justify;
    line-height: 1.7;
    margin: 0px 55px;
  }
}

As you can see, there is a reference to a javascript file. I use this to create a conditional page break if headers 2 to 6 happen to be the last line in the page or there is text preceding them.

document.addEventListener('DOMContentLoaded', function() {
  const headers = document.querySelectorAll('h2, h3, h4, h5, h6');
  headers.forEach(function(header) {
    const previousElement = header.previousElementSibling;
    const lastChildElement = header.parentElement.lastElementChild;
    
    if (previousElement || header === lastChildElement) {
      header.style.pageBreakBefore = 'always';
    }
  });
});

Everything works as expected.
However, I cannot seem to influence in any way the headers in terms of margins, font or font size.
Why could that be?
Thank you!

PDF export is kind of a black box because we can’t preview the output with the applied CSS to see if it’ll work or not. So… as much as it’s frowned upon, !important to the rescue unless you want to spend hours exporting over and over again to see what works or what doesn’t.

I rearranged a few things and added the excessive size + orange to make sure it was working, but this seems to work exporting from the default theme. You can add more individual h2~h6 rules if you need them. I’m not sure about the ATimport as I’ve never used a .js file in PDF export before.

Hopefully this helps a bit.

@import "pdf-print.js";
@media print {
  @page {
    margin-top: 1.1in;
    margin-bottom: 1.3in;
  }
  p {
    font-family: "Times New Roman", Times, serif;
    font-size: 14px;
    text-align: justify;
    line-height: 1.7;
    margin: 0px 55px;
  }
  :is(h1, h2, h3, h4, h5, h6) {
    font-family: "Times New Roman", Times, serif !important; 
    color: orange !important;
    text-align: center;
  }
  h1 {
    font-size: 50px !important;
    margin-top: 30px !important;
    margin-bottom: 30px !important;
    page-break-before: always;
  }
}

1 Like

Hello ariehen. Thank you so much for taking the time to test this out. You have given me the solution to my problem by pointing out that certain header values require the !important property to override whatever the builtin PDF converter does.
Now everything works like a charm. My final versions of the CSS and JS script, if that can help anyone else, are:

@import "pdf-print.js";
@media print {
  @page {
    margin-top: 1.1in;
    margin-bottom: 1.3in;
  }
  h1, h2 { 
    text-align: center;
    font-family: "Times New Roman", Times, serif !important;
  }
  h1 {
    font-size: 18px !important;
    page-break-before: always;
    margin: 0px 65px 45px !important;
  }
  h2 {
    font-size: 15px !important;
    margin: 30px 65px !important;
  }
  p {
    font-size: 13px;
    font-family: "Times New Roman", Times, serif;
    text-align: justify;
    line-height: 1.7;
    margin: 0px 55px;
  }
}

and

document.addEventListener('DOMContentLoaded', function() {
  const headers = document.querySelectorAll('h2, h3, h4, h5, h6');
  headers.forEach(function(header) {
    const previousElement = header.previousElementSibling;
    const lastChildElement = header.parentElement.lastElementChild;
    
    if (previousElement || header === lastChildElement) {
      header.style.pageBreakBefore = 'always';
    }
  });
});

Thank you again for your help!

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.