.oneres

Skip to the calculator.

The above stands for One Resolution. In which I employ CSS to make a webpage the same resolution on every screen.

Warning: this is not recommended, since the screen will be super small on phones! With that in mind, I'm going to be working on your standard HTML page. In fact, this very page will be the example!

<!doctype html>
<html lang=en>
<meta charset=utf-8>
<meta name=viewport content="width-device-width,initial-scale=1.0">
<title>oneres</title>
<link href=oneres.css rel=stylesheet>

<div class=oneres>
  
  <h1>oneres.css</h1>
  
  <p>Everything else...
  
</div>

To begin with, let's choose a screen resolution! A quick web search has informed me 1024 x 768 is a thing, and it's small enough that I think most desktop screens will be fine viewing it, so I'm gonna go with that.

Keep in mind their ratio:

1024:768 = 4:3 ≈ 1.333

768:1024 = 3:4 = .75

Let's work things out in portrait mode first. This means the screen is taller than it is wide, as below.

We want the our div .oneres to fit within that rectangle without changing resolution or overflowing.

First, in the CSS, we take out the margins in the BODY, and set background color on both BODY and .oneres so we know what's going on.

body {
  margin:0;
  background: black;
}
.oneres {
  background: white;
}

To make this easier on us, let's change the HTML element's font size so that 1rem = "1px".

100vw = "1024px" 0.09765625vw = "1px"

html {
  font-size: 0.09765625vw; /* 1rem = 1px */
}
Now we can either use:
.oneres {
  width: 100vw;
  height: 75vw;
}

or:

.oneres {
  width: 1024rem;
  height: 768rem;
}

...and the result should be the same. I'll stick with the first one because it's simpler and least likely to fail due to the computer's calculations deeming extra digits irrelevant. It happens, okay!

Let's go ahead and set-up a few more basics in .oneres:

.oneres {
  background: white;
  width: 100vw;
  height: 75vw;
  font-size: 16rem;
  overflow: auto;
  padding: 10rem;
  box-sizing: border-box;
  position: absolute;
  top:50%;
  transform: translateY(-50%);
}

I'll expound on the new styles one by one.

font-size: 16rem
We're basically setting the font-size to 16px, which is the standard and recommended minimum font size on most browsers. Now 1em = 16rem = "16px".
overflow: auto
So that .oneres will scroll when the page gets too long. Now nothing should be sticking out.
padding: 10rem
Usually, the BODY will start out with, like, 10px of margin space all around, right? So I put padding in to simulate that.
box-sizing: border-box
Now that I'm messing around with padding, this is important. Otherwise, .oneres will be 1024rem + 10rem + 10rem wide and 768rem + 10rem + 10rem tall.
position: absolute;
top: 50%;
transform: translateY(-50%);
This, I did to center .oneres in the middle of the screen. The absolute position combined with top: 50% moved .oneres so its top edge is exactly halfway down the page. The transform: translateY(-50%) moves it back up 50% of the DIV's own height, so now it's in the middle.

And so we're done!

... With the first half. If you've been working along and haven't noticed it yet, when the screen gets too wide, it starts overflowing all over the place and now there's too many scrollbars and the text is too big, blah blah blah.

It doesn't work as well when the window is wider than this:

This is where we start using out @media tool, and where knowing the ratio becomes most useful.

When the window's ratio is taller than 4:3 (4:any number greater than 3), everything works out just fine. However, when The window's ratio is wider than 4:3 (any number greater than 4:3), it gets jank.

Our limiting factor now is the height. So we base the "px" on 100vh now. Note vh, not vw.

100vh = "768px" 0.13020833333333334vh = "1px"

Wow, that's an ugly number, but it's what we got. I'll shorten it a bit since it's such a miniscule difference, it won't matter how accurate I try to be. There's only so many pixels in a computer, it can't be that accurate.

@media (max-height: 75vw) {
  html {
    font-size: 0.13020833vh;
  }
  .oneres {
    height: 100vh;
    width: 1.333vh;
    top: unset;
    left: 50%;
    transform: translateX(-50%);
  }
}

Note that I also changed the width and height in .oneres to reflect that we're working with the viewport height instead of the viewport width. Also, I'm now centering .oneres in the middle horizontally instead of vertically.

Yeah, the second half was that short. Everything should be working now! The final CSS for this page looks like this:

html {
  font-size: 0.09765625vw; /* 1px */
}

body {
  margin:0;
  background: black;
  overflow: hidden;
}

.oneres {
  background: white;
  width: 100vw;
  height: 75vw;
  font-size: 16rem; /* 16px */
  overflow: auto;
  padding: 10rem;
  box-sizing: border-box;
  position: absolute;
  top:50%;
  transform: translateY(-50%);
}

@media (min-width: 133.333vh) {
  html {
    font-size: 0.13020833vh; /* 1px */
  }
  
  .oneres {
    height: 100vh;
    width: 133.333vh;
    top: unset;
    left: 50%;
    transform: translateX(-50%);
  }
}

So with that, I can make a cheat sheet of formulas you'll need when deciding your own resolution, knowing the WIDTH and HEIGHT in pixels that you want the page to be. In fact...


Calculator

html {
  font-size: vw;
}

body {
  margin:0;
  background: black;
  overflow: hidden;
}

.oneres {
  background: white;
  width: 100vw;
  height: vw;
  font-size: 16rem;
  overflow: auto;
  padding: 10rem;
  box-sizing: border-box;
  position: absolute;
  top:50%;
  transform: translateY(-50%);
}

@media (min-width: vh) {
  html {
    font-size: vh;
  }
  
  .oneres {
    height: 100vh;
    width: vh;
    top: unset;
    left: 50%;
    transform: translateX(-50%);
  }
}