Center a sans-serif font vertically with exact precision while adjusting the font size

My issue is an expansion of a previous problem I mentioned in another question, which can be found here Vertically align sans-serif font precisely using jquery/css.

To summarize: I am aiming to align two divs containing text, with one positioned above the other, so that the beginning of the letter A (specifically the lower left point) always aligns with the vertical line of H. Here's an example of what I'm trying to achieve:

The top div has a variable font-size and I want the bottom div to adjust its alignment according to that font size. This adjustment is necessary as I scale my font size based on the window's dimensions.

Check out this demo on jsfiddle.

HTML

<div id="Hideheader" class="Header" style="position: absolute;font-size:40pt;padding:0px;visibility: hidden;width:auto;height:auto;">HEADER</div>
<div id="header" class="Header">HEADER</div>
<div id="menubar" class="menubar">
    <div class="menubutton_left"><a href="#" id="WorkButton">A</a>
    </div>
    <div class="menubutton_middle"><a href="#" id="AboutButton">B</a>
    </div>
    <div class="menubutton_right"><a href="#" id="ContactButton">C</a>
    </div>  <span class="stretch"></span>

</div>

CSS

div.Header {
    font-family:sans-serif;
    text-align:justify;
    white-space: nowrap;
}
div.menubar {
    text-align: justify;
    -ms-text-justify: distribute-all-lines;
    text-justify: distribute-all-lines;
    margin-bottom: 0px;
    position: relative;
}
div.menubutton_left, div.menubutton_middle, div.menubutton_right {
    vertical-align: top;
    display: inline-block;
    *display: inline;
    zoom: 1;
    width:60px;
}
div.menubutton_left {
    margin-left:12px;
}
div.menubutton_middle {
    text-align: center;
}
div.menubutton_right {
    text-align: right;
}
.stretch {
    border: 2px dashed #444;
    width: 100%;
    display: inline-block;
    font-size: 0;
    line-height: 0
}

JAVASCRIPT

resizeHead("#Hideheader", "#header");

$(window).resize(function() {
  resizeHead("#Hideheader", "#header");
});

function resizeHead(p1, p2) {
    var fontsize = parseFloat($(p1).css("font-size"));
    var spacing = parseFloat($(p1).css("letter-spacing"));
    var initWidth = $(p1).width();
    initWidth = initWidth - spacing;
    var outWidth = $(p2).width();

    var s = outWidth / initWidth;
    s = fontsize * s;
    $(p2).css({
        "font-size": s
    });
}

Test resizing your browser window. The alignment issues become more evident at smaller font sizes.

Answer №1

It's possible that I may not fully grasp your query.. However, after reviewing your fiddle, it seems I understand what you're aiming for. Here are some suggestions:

1: Avoid using JavaScript to adjust font sizes. Consider utilizing relative units such as vw, vh, or vmin. These units adjust their size based on the parent container, like so: font-size: 20vw.

This method is much lighter compared to using JavaScript for every window resize event.

2: You've specified a fixed width for your divs, causing layout issues when they shrink below 60px. Remove this fixed width and opt for dynamically calculated widths using calc(100% / 3), ensuring all three divs are correctly positioned.

3: The margin-left on your first div disrupts the layout. Instead, add the margin to the <a> tag within the div:

div.menubutton_left a {
    margin-left:12px;
}

For an updated fiddle incorporating these changes (without any JavaScript), check out the link here: http://jsfiddle.net/ksuTQ/7/

Answer №2

I've encountered a similar issue with my applications in the past, and while I admit my solutions were not always elegant, they did get the job done. @LcSalazar's post is definitely worth checking out, although I have faced challenges in configuring the rest of my page after using elements with relative positioning. However, it seems like you are already going down that path. Start by trying @LcSalazar's suggestion first, and if you're feeling adventurous, give my solution a shot. Consider experimenting with elements like span instead of div, but be aware that this may impact your project significantly.

The main obstacle lies in HTML's limited capability to gather TextMetrics, which is essentially what you're seeking. While canvas elements offer TextMetrics providing width information, obtaining height data proves to be more challenging.

var myCanvas = document.createElement('canvas');
var myContext = myCanvas.getContext('2d');

var myText = "I'm exploring canvas for text measurements!";

var textMetrics = myContext.measureText(myText);

var textWidth = textMetrics.width;

Unfortunately, determining height remains elusive within HTML. Here's an approach I've utilized in the past:

var hiddenDiv =  document.createElement('div');
hiddenDiv.style.visibility = 'hidden';
hiddenDiv.style.position = 'absolute';
hiddenDiv.style.top = '0px';
hiddenDiv.style.left = '0px';
document.body.appendChild(hiddenDiv);

var myText = "Measuring text through a discreet div";

function getTextHeight(text, font)
{
   hiddenDiv.style.font = font;
   hiddenDiv.innerHTML = text;

   return hiddenDiv.clientHeight;
}

var myFont = 'normal 13px Verdana';

var textHeight = getTextHeight(myText, myFont);

You can leverage the obtained text height for resizing or aligning purposes as needed. I chose not to integrate it directly into your project, aiming instead to present a simplified method for acquiring text height without extensive coding. Always remember to define the div's font before measuring it! Hopefully, this provides some assistance!

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

The function you are trying to access does not exist in this.props

Trying to pass this.state.user to props using the isAuthed function is resulting in an error: this.props.isAuthed is not a function . The main objective is to send this.state.user as props to App.js in order to show or hide the Sign out button based on ...

Parameterized Azure Cosmos DB Stored Procedure

I am currently learning about Azure Cosmos Db, and I am in the process of developing a simple JavaScript stored procedure that will return a document if a specific Id is provided. However, when I run the stored procedure, I do not receive a "no docs foun ...

Prevent Text Overflow in CSS, Material-UI, and React styling efforts

I am facing an issue where the cardTitle is overlapping the Card when the text is too long. Currently, I am manually setting a static maxWidth, but I would prefer for it to adjust based on the size of the Card. Is there a way to achieve this dynamically? ...

The installation of the material ui package was unsuccessful

C:\Users\User\Desktop\client4>npm i @material-ui/icons npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resolving: [email protected] npm ERR! Found: [email protected] ...

What are the steps to incorporate @svgr/webpack into turbopack within a next.js project?

I'm encountering an issue with turbopack and @svgr/webpack in my project. According to the documentation, they should work together but it's not cooperating. When I run the project without using --turbo (turbopack), everything functions as expec ...

`Display communications using JQuery and C#`

I am aiming to create a messaging system on a website where users can send messages to each other. Each message will have a button that closes the message and updates the database to mark it as read. My main requirements include: The page should not rel ...

Every time a button is clicked on the interface, a new element or button will appear. This functionality is made possible through

Currently diving into a new React.js project as a beginner. I have a little challenge in the code snippet below - looking to add a button that displays "Hello World" every time it's clicked using setState. Can anyone guide me on enhancing the DisplayM ...

Exploring the Ins and Outs of Debugging JavaScript in Visual Studio Using

I encountered a peculiar issue while testing some code. When the program is executed without any breakpoints, it runs smoothly. However, if I introduce a breakpoint, it halts at a certain point in the JSON data and does not allow me to single-step through ...

Error: The Node Express Server is unable to locate the requested resource at "/

const http = require("http"); const myApp= require('./myApp'); const portNumber = 8080; const myServer = http.createServer(myApp); myServer.listen(portNumber) ...

Eliminating an element from an array based on a single criterion

Here's a question that might seem simple to some: Let's say I have an array like this... var array = [ {id: 1, item: "something", description: "something something"}, {id: 2, item: "something else", description: "something different" ...

Jasmine - What is the best way to simulate a finally block?

After creating a controller in my test, I encountered an issue with the updateActionList function... this.createScope = function(scope) { if (scope) { this.scope = scope; } else { this.scope = $rootScope.$new(); } this.contro ...

Capturing the action phase in Liferay to change the cursor to 'waiting' mode

I'm currently working on a large Liferay project and have encountered a specific issue: Whenever something in the system is loading or processing, I need to change the cursor to a waiting GIF. While this is simple when using Ajax, there are many inst ...

Apache causes HTML download tag to malfunction

I have an HTML file that includes the following code: <a href="/Library/WebServer/Documents/file.zip" download="file.zip"> Download here </a> When I test this HTML page on Chrome, it successfully allows me to download the file. However, when ...

A guide to testing window.pageYoffset in webdriverIO using chai assertions

When conducting a selenium test using WebDriverIO and Chai, I encountered the need to capture the position of window.pageYoffset. Unfortunately, I was unable to find a direct way to do this in WebDriverIO. My initial attempts involved: browser.scroll(0, 2 ...

Component fails to re-render after token refresh on subsequent requests

Here is my axios-hoook.js file, utilizing the axios-hooks package. import useAxios from 'axios-hooks'; import axios from 'axios'; import LocalStorageService from './services/local-storage.service'; import refreshToken from &ap ...

tips on setting the time format in dimple.js

Trying to create a multi-line graph using dimple.js based on some sample code. I have flattened my JSON into an array and thought I had the code down, but I'm stuck. I am including these 2 libraries (using cloudflare dimple for security reasons): &l ...

Exploring the Power of JQuery with Hover Effects and SlideToggle

I was struggling to keep the navbar displaying without it continuously toggling when my pointer hovered over it. I just wanted it to stay visible until I moved my pointer away. <script> $(document).ready(function(){ $(".menu-trigger").hover(funct ...

Once the form has been loaded without any information, go ahead and submit

I have created my index.php file with the following code: <script src="js/jquery-1.9.1.js"></script> <script> $(document).ready(function(){ $("#sload").load('save1.php',function(forma){ $(".csave").click(function(){ ...

The background gently fades away, directing all attention to the popup form/element

After extensive searching, I have yet to find a straightforward solution that seems to be a standard practice on the web. My goal is to create a form that appears in the center of the screen when a button is clicked using CSS or jQuery. I would like the ...

Is it limited to using url routes for clients to communicate with servers in a node.js web application?

Utilizing the Rest API allows the client to interact with the backend through URL routes. When the page loads, the route can be used directly, and ajax requests can be made without reloading the page. Both methods use URL routes to send a request to the se ...