JSFiddle - React, Tailwind, and code Playground

by Jens Kühn

HTML

<!-- The header element will appear on the top of each page of this invoice document. -->
<header>
  <div class="headerSection">
    <!-- As a logo we take an SVG element and add the name in an standard H1 element behind it. -->
    <div class="logoAndName">
      <svg>
        <circle cx="50%" cy="50%" r="40%" stroke="black" stroke-width="3" fill="black" />
      </svg>
      <h1>Logo &amp; Name</h1>
    </div>
    <!-- Details about the invoice are on the right top side of each page. -->
    <div class="invoiceDetails">
      <h2>Invoice #100</h2>
      <p>
        07 March 2021
      </p>
    </div>
  </div>
  <!-- The two header rows are divided by an blue line, we use the HR element for this. -->
  <hr />
  <div class="headerSection">
    <!-- The clients details come on the left side below the logo and company name. -->
    <div>
      <h3>Invoice to</h3>
      <p>
        <b>Client Name</b>
        <br />
        123 Alphabet Road, Suite 01
        <br />
        Indianapolis, IN 46260
        <br />
        <a href="mailto:[email protected]">
          [email protected]
        </a>
        <br />
        317.123.8765
      </p>
    </div>
    <!-- Additional details can be placed below the invoice details. -->
    <div>
      <h3>Due Date</h3>
      <p>
        <b>07 April 2021</b>
      </p>
      <h3>Amount</h3>
      <p>
        <b>$3,500</b>
      </p>
    </div>
  </div>
</header>

<!-- The footer contains the company's website and address. To align the address details we will use flexbox in the CSS style. -->
<footer>
    <a href="https://companywebsite.com">
      companywebsite.com
    </a>
    <a href="mailto:[email protected]">
      [email protected]
    </a>
    <span>
      317.123.8765
    </span>
    <span>
      123 Alphabet Road, Suite 01, Indianapolis, IN 46260
    </span>
</footer>

<!-- In the main section the table for the separate items is added. Also we add another table for the summary, so subtotal, tax...

CSS

/* 
Import the desired font from Google fonts. 
*/
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;600;700&display=swap');

/* 
Define all colors used in this template 
*/
:root{
  --font-color: black;
  --highlight-color: #60D0E4;
  --header-bg-color: #B8E6F1;
  --footer-bg-color: #BFC0C3;
  --table-row-separator-color: #BFC0C3;
}

@page{
  /*
  This CSS highlights how page sizes, margins, and margin boxes are set.
  https://docraptor.com/documentation/article/1067959-size-dimensions-orientation

  Within the page margin boxes content from running elements is used instead of a 
  standard content string. The name which is passed in the element() function can
  be found in the CSS code below in a position property and is defined there by 
  the running() function.
  */
  size:A4;
  margin:8cm 0 3cm 0;

  @top-left{
  	content:element(header);
  }

  @bottom-left{
  	content:element(footer);
  }
}

/* 
The body itself has no margin but a padding top & bottom 1cm and left & right 2cm.
Additionally the default font family, size and color for the document is defined
here.
*/
body{
  margin:0;
  padding:1cm 2cm;
  color:var(--font-color);
  font-family: 'Montserrat', sans-serif;
  font-size:10pt;
}

/*
The links in the document should not be highlighted by an different color and underline
instead we use the color value inherit to get the current texts color.
*/
a{
  color:inherit;
  text-decoration:none;
}

/*
For the dividers in the document we use an HR element with a margin top and bottom 
of 1cm, no height and only a border top of one millimeter.
*/
hr{
  margin:1cm 0;
  height:0;
  border:0;
  border-top:1mm solid var(--highlight-color);
}

/*
The page header in our document uses the HTML HEADER element, we define a height 
of 8cm matching the margin top of the page (see @page rule) and a padding left
and right of 2cm. We did not give the page itself a margin of 2cm to ensure that
the background color goes to the edges of the...