Zooming Fluidity

These are my specifications:

  1. Font size should adjust fluidly from 14px to 22px between 1280 and 1920
  2. Users must be able to zoom normally

Finding a solution that accomplishes both has been challenging. I've explored CSS Tricks simplified fluid approach, but using any kind of vw renders the zoom feature ineffective.

  • clamp(0.875em, 1.146vw, 1.375em) - does not scale in alignment with regular zoom levels, only about 5% as opposed to 50%
  • clamp(0.875em, 1.4vw - 0.3em, 1.375em)
    - encounters issues with minimum and maximum values, resulting in shrinkage during zoom
  • calc(0.875em + 8 * (100vw - 1280) / 640)
    - fails to respond accurately to zoom adjustments

Answer №1

When working with CSS, there are certain limitations to calculations. For example, when performing multiplication, one of the numbers must be unitless (source). This means that certain formulas, like the one we were aiming for, cannot be achieved solely in CSS:

clamp(14px, calc(1.09375vw + (0.05208vw * (100vw - 1280px) / 640)), 22px)

To meet all requirements, we need to handle this situation using JavaScript:

let element = document.querySelector('.scale');

function updateFontSize() {
  let size = 14;
  let vpWidth = window.innerWidth;
  let zoom = ((window.outerWidth) / window.innerWidth);

  if (vpWidth >= 1920) {
    size = 22;
  } else if (vpWidth <= 1280) {
    size = 14;
  } else {
    //calculate
    size = 14 + (vpWidth - 1280) * 8 / 640;
  }
  //apply zoom
  size *= zoom;

  element.style.setProperty('--font-size', size + 'px');

  document.getElementById('stats').innerText = 'Viewport Width: ' + vpWidth + 'px  \nZoom: ' + (zoom.toFixed(2) * 100).toFixed(0) + '%';
}


window.addEventListener('resize', () => updateFontSize());
updateFontSize();
p {
  margin: 0;
  padding: 0;
}

.f14 {
  font-size: 14px;
}

.f22 {
  font-size: 1.376rem;
}

.scale {
  --font-size: 14px;
font-size: var(--font-size);
}

@media screen and (min-width: 1280px) and (max-width: 1980px) {
  body {
    background-color: wheat;
  }
}
<div id=stats></div>
<hr><br>
<p class=f14>Lorem ipsum dolor sit amet.| 14px</p>
<p class=scale>Lorem ipsum dolor sit amet.| scaling</p>
<p class=f22>Lorem ipsum dolor sit amet.| 22px</p>

Due to StackOverflow's use of iframes for output, you may not see the actual results running the snippet here. It is recommended to switch to Full Page mode or run the code in a separate local HTML file.
The method I used to determine the zoom level in the above code does not work within an iframe. Finding the browser's zoom level can be a challenging task. More information can be found in this thread.

I did not obtain the perceived versus required font size at 150% zoom. Additionally, it would be helpful to know what should occur if the user zooms out to 50%.

Answer №2

In my opinion, achieving this task solely with CSS might not be feasible. However, incorporating JavaScript offers a straightforward solution. Kindly inform me if I have misunderstood any of the requirements.

Resolution

To address this issue, I am resetting the --fluid-size CSS variable during the load and resize events by executing the resetFluidSize function. It is important to note that this process may impact performance as it triggers reflows each time it is executed, without any optimizations for simplicity.

I have utilized the outerWidth method to prevent variations in zoom levels from affecting the proper scaling, ensuring consistent computed style regardless of page zoom settings.

Following calculations, I update the CSS variable using document.body.style.setProperty.

Important Note

To view accurate values, launch the code snippet in full-page mode.

window.addEventListener('load', () => {
  resetFluidSize();
  window.addEventListener('resize', resetFluidSize);
});

const
  minSize = 14,
  maxSize = 22;

function resetFluidSize() {
  const
    factor = (window.outerWidth - 1280) / 640,
    lerp = minSize + (maxSize - minSize) * factor,
    clamp = Math.max(minSize, Math.min(maxSize, lerp)),
    fluidSize = `${clamp}px`;

  document.body.style.setProperty('--fluid-size', fluidSize);

  /* Update the feedback display. */
  document.getElementById('fluid-text').setAttribute('currentSize', fluidSize);
}
:root {
  --fluid-size: 16px;
}

#fluid-text {
  font-size: var(--fluid-size);
}


/* The following styles are for visual feedback purposes only */

p {
  border-right: 1px solid black;
  margin: 0;
  width: fit-content;
  position: relative;
}

p::after {
  content: attr(currentSize);
  position: absolute;
  left: 100%;
}
<body>
  <p style="font-size: 14px;" currentSize="14px">
    Lorem ipsum
  </p>
  <p id="fluid-text">
    Lorem ipsum
  </p>
  <p style="font-size: 22px;" currentSize="22px">
    Lorem ipsum
  </p>
</body>

Further Instructions

If you wish to test it locally, feel free to utilize this index.html provided on GitHub Gist.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Preserving proportions in CSS using both width and height measurements

My objective is to set an aspect ratio (for example, 4:3) for a DIV and all its children with the styles WIDTH:100% and HEIGHT:100%. Initially, this method works well by setting the parent's WIDTH:100% and then adding PADDING-BOTTOM: 75%; // (3/4)*1 ...

Horizontal alignment of Bootstrap columns is not working as expected

While attempting to integrate Bootstrap elements into my portfolio, I encountered issues with aligning columns. Currently, the only columns I have added are in the "welcome-section" (Lines 40-52), but they refuse to align horizontally. I've tried tro ...

In next js, the component exceeds 100% overflow when padding is added

https://i.sstatic.net/W30tk.png Hey there, I've been encountering some issues with next js and styled-components. I have a parent component (sc-hgRfpC lbMBdR) with a width of 400px, and swap-div-5 with a width: 100%. However, when I add padding: 12px ...

Positioned footer without predetermined height

I am having trouble with positioning the footer so that it always stays at the bottom of the page. When there is not enough content on the page, the footer does not reach the bottom as desired. Additionally, the footer does not have a fixed height. Below i ...

Add fresh inline designs to a React high-order component creation

Applying a common HOC pattern like this can be quite effective. However, there are instances where you may not want a component to be wrapped, but rather just extended. This is the challenge I am facing here. Wrapper HOC const flexboxContainerStyles = { ...

Update the dropdown field selection to the color #333 with the help of javascript

I am facing an issue with a dropdown field that has placeholder text and options to select. Initially, both the placeholder text and the options were in color #333. However, I managed to change the color of the placeholder text to light grey using the foll ...

Displaying an iFrame with a height that excludes the header section

My website contains an iframe with a height of 100% and a div positioned above it with a height of 70px. The issue is that the iframe overflows the page, causing the scrollbar to extend beyond the visible area. I am looking for a solution to adjust the ifr ...

Synchronizing a webpage on various devices

I've encountered a dilemma with my code where the alignment of elements on my website looks different when viewed on a different computer. The pages were developed on my MacBook Pro and display correctly, but when I view them on my iMac, everything is ...

Tips on adjusting my script to focus on particular text within a div in HTML

I'm currently learning how to code and working on a text generator that allows users to edit text and export it as .DOCX. I came across this script called jsfiddl on the website npmjs, which enables exporting HTML to .DOCX. However, I'm having tr ...

Creating a Bootstrap 4 column form label with a maximum width limit

I am currently working on creating a form within a full-width fluid layout that consists of 2 columns - the label column and the inputs column. The issue I'm running into is that due to the wide screens on fluid layouts, the col-2 label appears too l ...

Users who are utilizing Internet Explorer are unable to complete the search input field on my website

Hello, I am in the process of creating a website that frequently uses lengthy search terms. To optimize user experience, I have implemented a dropdown search bar inspired by the bootsnipp example below. While I have applied some custom styling to the desig ...

What is the best way to create space between three Bootstrap columns without causing them to wrap onto a new

.background-color { background-color: lightgrey; height: 200px; border: 1px solid black; } <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoa ...

Differences between HTML viewports and media queries

For simple webpages, my general rule is to utilize viewport units as they provide a lot of flexibility to the website. However, when dealing with complex webpages, I usually opt for media queries. In some cases, especially intermediate ones, I find it ben ...

JavaScript - Image style alterations are not operating as expected

Let me break it down for you: onmouseover="imageOn(bg-index);" onmouseout="imageOff(bg-index);" I've got these two attributes set on a table tagged with ID table-title. These functions are included in an external JS file: If the name is 'bg-i ...

The animations in fontawesome 6.2 are completely ineffective

I've been struggling to make a spinner icon spin on my webpage. I made sure to download the latest version of font awesome and created a simple HTML file to troubleshoot the issue. Take a look at the HTML code below: <!doctype html> <html la ...

Utilize JavaScript to trigger a gentle notification window to appear on the screen

Whenever I click a link on my HTML page, I want a popup element (just a div box) to appear above the clicked link. I have been using JavaScript for this, but I am facing an issue where the popup element appears below the link instead of above it. Can you ...

using boostrap modal leads to background displacement

Just starting out with bootstrap and encountering a modal bug: when I click on a modal button, the background shifts to the right by 15px. My current bootstrap template is version 3.3.0. I attempted to update to the latest 3.3.4 version, but unfortunately ...

Turning a two-dimensional CSS3 animation into a three-dimensional transformation

After successfully mastering movement of an image in 2D using CSS3, I'm now faced with the challenge of translating this into 3D movement. While I've researched transforms, they primarily focus on flipping and rotating, and I am more interested i ...

Within an HTML document, select one checkbox out of two checkboxes without utilizing JQuery

Is there a way to select only one checkbox out of two? I know it can be done easily using Jquery, but is there a default option in HTML for this as well? I have exactly 2 checkboxes. Thank you. code: <input type="checkbox" value="1" name="foo" /> ...

Display the div only when certain other divs have been clicked

I am fairly new to jQuery (this is my second attempt at using it). I have searched for solutions on Google and StackOverflow, tried several approaches, but still can't solve the last part of my issue. Any assistance or direction would be greatly appre ...