<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Chris Douglas</title>
    <description>The latest articles on DEV Community by Chris Douglas (@chrisdouglas_vitcox).</description>
    <link>https://dev.to/chrisdouglas_vitcox</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4221734%2Fad3f9750-4cc5-4694-a9c7-194ad369cb33.png</url>
      <title>DEV Community: Chris Douglas</title>
      <link>https://dev.to/chrisdouglas_vitcox</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/chrisdouglas_vitcox"/>
    <language>en</language>
    <item>
      <title>The Math of Fitting One 4K Wallpaper to Every Screen: Aspect Ratios, Crops and Scaling</title>
      <dc:creator>Chris Douglas</dc:creator>
      <pubDate>Tue, 03 Nov 2026 04:15:14 +0000</pubDate>
      <link>https://dev.to/chrisdouglas_vitcox/the-math-of-fitting-one-4k-wallpaper-to-every-screen-aspect-ratios-crops-and-scaling-58mf</link>
      <guid>https://dev.to/chrisdouglas_vitcox/the-math-of-fitting-one-4k-wallpaper-to-every-screen-aspect-ratios-crops-and-scaling-58mf</guid>
      <description>&lt;p&gt;I spend more time than I'd like to admit fitting images to screens: a 16:9 monitor, a 21:9 ultrawide, a 19.5:9 phone, a 4:3 tablet. Every device wants something slightly different, and the "fill" setting in your OS just guesses. Once you understand the arithmetic behind it, you can crop a single high-resolution image cleanly for all of them. Here's the reasoning I use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Aspect ratio is the whole game
&lt;/h2&gt;

&lt;p&gt;An aspect ratio is width divided by height. A 3840×2160 image is 16:9, or about 1.778. Common targets:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Device&lt;/th&gt;
&lt;th&gt;Typical resolution&lt;/th&gt;
&lt;th&gt;Ratio&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Standard monitor&lt;/td&gt;
&lt;td&gt;2560×1440, 3840×2160&lt;/td&gt;
&lt;td&gt;1.778 (16:9)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;16:10 laptop&lt;/td&gt;
&lt;td&gt;2560×1600&lt;/td&gt;
&lt;td&gt;1.6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ultrawide&lt;/td&gt;
&lt;td&gt;3440×1440&lt;/td&gt;
&lt;td&gt;~2.389 (21:9)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Modern phone&lt;/td&gt;
&lt;td&gt;1179×2556&lt;/td&gt;
&lt;td&gt;~0.461 (portrait)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tablet&lt;/td&gt;
&lt;td&gt;2048×1536&lt;/td&gt;
&lt;td&gt;1.333 (4:3)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;When the source ratio and the target ratio differ, you have three choices: crop, letterbox (add bars), or stretch. Stretching distorts, letterboxing wastes screen, so cropping is almost always right for wallpapers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Computing the largest crop
&lt;/h2&gt;

&lt;p&gt;For a source of width &lt;code&gt;W&lt;/code&gt; and height &lt;code&gt;H&lt;/code&gt;, and a target ratio &lt;code&gt;r = targetW / targetH&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;largestCrop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;W&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;H&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sourceRatio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;W&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;H&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sourceRatio&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// source is wider: keep full height, trim width&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;w&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;H&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="na"&gt;h&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;H&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// source is taller or equal: keep full width, trim height&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;w&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;W&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;h&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;W&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;largestCrop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3840&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2160&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2560&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1600&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// { w: 3456, h: 2160 }  16:10&lt;/span&gt;
&lt;span class="nf"&gt;largestCrop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3840&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2160&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3440&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1440&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// { w: 3840, h: 1607 }  ultrawide&lt;/span&gt;
&lt;span class="nf"&gt;largestCrop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3840&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2160&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1179&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2556&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// { w: 996,  h: 2160 }  phone&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the phone case: a portrait crop from a landscape 4K image keeps only about a quarter of the width. That's why phone wallpapers cut from desktop art often feel "zoomed in". Its height (2160) is still below the phone's 2556 pixels, so it will be upscaled slightly, which is fine for soft abstracts and less fine for sharp detail.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to put the crop
&lt;/h2&gt;

&lt;p&gt;The largest crop tells you the size. Position is a separate decision. Centre-cropping is the default, but it isn't always best. Three heuristics I use:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Rule of thirds.&lt;/strong&gt; If the subject sits on a third line in the source, keep it on a third line in the crop by anchoring the crop window so the subject lands at 1/3 or 2/3 of the new width.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leave room for UI.&lt;/strong&gt; On a phone, the top quarter holds the clock and the bottom holds controls. Shift the crop so the subject sits in the middle band.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ultrawide horizons.&lt;/strong&gt; For 21:9 you're trimming height, so decide whether the sky or the foreground matters more and anchor top or bottom accordingly.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A simple anchored version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;cropAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;W&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;H&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;focusX&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;focusY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;largestCrop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;W&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;H&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;focusX&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;W&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;w&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;W&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;w&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;focusY&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;H&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;H&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;focusX&lt;/code&gt; and &lt;code&gt;focusY&lt;/code&gt; are the subject's position as fractions of the source. Clamping keeps the window inside the image.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scaling after the crop
&lt;/h2&gt;

&lt;p&gt;After cropping, resize to the device's exact resolution. Downscaling (cropped region bigger than the screen) is safe; use a good filter such as Lanczos or the browser's &lt;code&gt;imageSmoothingQuality = "high"&lt;/code&gt; on a canvas. Upscaling more than about 20 percent starts to show softness, so prefer a source large enough that you're always scaling down.&lt;/p&gt;

&lt;h2&gt;
  
  
  Doing it in the browser
&lt;/h2&gt;

&lt;p&gt;All of this works client-side with a &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt;: load the image, compute the crop, call &lt;code&gt;drawImage&lt;/code&gt; with the source rectangle and the destination size, and export with &lt;code&gt;toBlob&lt;/code&gt;. Nothing needs to leave the user's machine, which is nice for privacy and speed. If you'd rather not write it yourself, the &lt;a href="https://vitcox.com/tools" rel="noopener noreferrer"&gt;VITCOX browser tools&lt;/a&gt; do this kind of fit-and-crop for common screen sizes, and they're handy for checking your own maths against a working implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Compare ratios first; size follows from that.&lt;/li&gt;
&lt;li&gt;The largest crop keeps one full dimension and trims the other.&lt;/li&gt;
&lt;li&gt;Position the crop around the subject and the device's UI zones.&lt;/li&gt;
&lt;li&gt;Always scale down from a bigger source when you can.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The example image below is an AI-generated 4K city scene, which crops nicely to ultrawide because the interesting detail runs horizontally across the frame.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fb33m2w5urk3ca4m9cqnr.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fb33m2w5urk3ca4m9cqnr.jpg" alt="AI-generated 4K aerial wallpaper of waterfront city blocks beside deep blue water, used as a cropping example" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>design</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
