'How do I reliably draw a 1px border around the viewport?

I'm trying to work out how to draw a 1px border around the viewport. I would have thought this would do it, but it doesn't. It mostly draws the border, but when resizing the browser the right and bottom border constantly disappear.

<!DOCTYPE html>
<html>

<head>
  <title>Something</title>
  <style>
    * {
      box-sizing: border-box;
    }
    
    html,
    body {
      height: 100%;
    }
    
    body {
      margin: 0;
      background-color: blue;
      border: 1px solid red;
    }
  </style>
</head>

<body>
</body>

</html>

Cropped border



Solution 1:[1]

I would do it like below:

html::after {
  content:"";
  position:fixed;
  top:0;
  left:0;
  right:0;
  bottom:0;
  border:1px solid red;
  pointer-events:none;
}

Solution 2:[2]

Can't reproduce your problem, but a thought could be to use an outline instead. It uses almost the same syntax as border, but you can add a negative outline-offset to make it like an "inset shadow".

         html, body {
            height: 100%;
         }
         body {
            margin: 0;
            background-color: blue;
            outline: 1px solid red;
            outline-offset: -1px;
         } 
<html>
   <body>
   </body>
</html>

Solution 3:[3]

you can use a pseudo-elemnt like in this case that spans 100vh and 100vw and has a position fixed. However the entire rest must be wrapped aswell and use an overflow rules as otherwise the body scrollbar will cut away the right side border.

body {
  margin: 0;
}

.viewport-border {
  height: 100vh;
  width: 100vw;
  position: fixed;
  top: 0;
  border: 1px solid red;
  box-sizing: border-box;
}

.content {
  height: calc(100vh - 7px);
  width: calc(100vw - 7px);
  position: fixed;
  top: 1px;
  left: 1px;
  box-sizing: border-box;
  overflow: auto;
  margin: 5px;
}
<div class="viewport-border"></div>

<div class="content">
  <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata
    sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
    Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
  <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata
    sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
    Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
  <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata
    sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
    Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
  <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata
    sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
    Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
</div>

Solution 4:[4]

Assuming you want to put the border around the viewport (as the question suggests), and not around the document (as other answers seem to have assumed).

You'll want to use a position: fixed; element with a high z-index value:

<div id="viewportBorder"></div>
div#viewportBorder {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  border: 1px solid red;
  pointer-events: none;
  z-index: 999999;
}

Here it is in action:

body {
  background: #09f;
}

div#viewportBorder {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  border: 1px solid red;
  pointer-events: none;
  /* not technically needed in this example, but you might need it in your project */
  z-index: 999999;
}

.spacer-to-allow-scrolling {
  height: 300vh;
  width: 100px;
  background-image: linear-gradient(to bottom, black, white);
  margin: auto;
}
<html>
 <body>
  <div id="viewportBorder"></div>
  <div class="spacer-to-allow-scrolling"></div>
 </body>
</html>

Update: thank you to Temani Afif for pointing this out:

worth to note that your element will hide everything and you cannot have any interaction with the content (clicking, selecting, etc) you may need to consider pointer-events:none

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Temani Afif
Solution 2 Rickard Elimää
Solution 3 tacoshy
Solution 4