Guide to positioning an element directly following the initial line of a title

I am attempting to position an HTML element beside the first line of a heading. To clarify, I have taken screenshots to illustrate the current appearance and desired outcome.

Current Appearance:

Desired Outcome:

In order to change the background of the title's first line to red, I utilized the ::first-line pseudo-selector.

So far, my attempts to add a text content in the ::after of the ::first-line have been unsuccessful due to limitations on adding html content to both ::before and ::after.

It is important to note that the "sunshines" are not images, but actual html elements:


<div className={css.container}>
   <div className={css.shine1}></div>
   <div className={css.shine2}></div>
   <div className={css.shine3}></div>
</div>

.container {
  position: absolute;
  display: inline;
  top: 20px;
  right: 5px;

  div {
    position: absolute;
    height: 5px;
    border-radius: 5px;
    background-color: $mainColor;
    transform-origin: bottom left;
  }
  .shine1 {
    width: 26px;
    transform: rotate(-95deg) translate(20px, 5px);
  }
  .shine2 {
    width: 32px;
    transform: rotate(-45deg) translate(20px);
  }
  .shine3 {
    width: 26px;
    transform: rotate(0deg) translate(15px);
  }
}

This code snippet is written in JSX with scss modules, but follows a similar syntax as HTML and CSS.

If you have any suggestions on how to achieve this, please share your ideas. It seems feasible considering CSS can determine the end of a line for background changes.

Answer №1

After some experimentation, I've come up with a solution.

While my approach may be considered unconventional, it has proven effective in all test cases I've considered.

To achieve this, I create a hidden duplicate of the first line that mirrors the title's properties. By determining the width of this duplicate, I can appropriately define the left property for my elements.

Here is the function I utilize to extract the first line of text:

const getFirstLine = el => {
  const text = el.innerHTML;

  // Manipulate innerHTML temporarily
  el.innerHTML = 'a';
  const singleLineHeight = el.offsetHeight;

  const arr = text.split(' ');

  let cur = '';
  let prev = '';

  for (let i = 0; i < arr.length; i++) {
    const restOfText = text.substring(prev.length, text.length);    
    const nextIndex =
      restOfText.indexOf(' ') === 0
        ? restOfText.substring(1, restOfText.length).indexOf(' ') + 1
        : restOfText.indexOf(' ');
        
    cur += restOfText.substring(0, nextIndex);
    el.innerHTML = cur;
    
    if (el.offsetHeight > singleLineHeight) {
      el.innerHTML = prev;      
      const firstLine = el.innerText;
      const indexOfSecondLine = prev.lastIndexOf('<');
      
      el.innerHTML = text;
      
      return firstLine;
    }
    
    prev += cur.substring(prev.length, cur.length);
  }
  
  el.innerHTML = text;
  return text;
};

If you decide to implement this method, ensure that you wait for the webpage fonts to load properly to obtain accurate width measurements.

document.fonts.ready.then(function () {})

To accommodate titles with the text-align: center; property, I incorporate a margin-left/right: auto; adjustment on the duplicate element which is factored into the calculated left value using:

parseInt(window.getComputedStyle(invisibleTitle).marginLeft)

While this workaround may not be ideal, it remains the most viable option given the lack of straightforward CSS solutions.

Answer №2

If it's possible to separate the two lines in the heading, follow this HTML structure:

<header>
    <div>
        <div class="first-line">
            <p>
                Sample title, pretty long
            </p>
            <div className={css.container}>
                <div className={css.shine1}></div>
                <div className={css.shine2}></div>
                <div className={css.shine3}></div>
            </div>
        </div>
        <p>
            That is wrapping into two lines
        </p>
    </div>
</header>

CSS:

header .first-line{
  position: relative;
  display: inline-block;
}
.container {
  position: absolute;
  display: inline;
  top: 20px;
  right: 5px;
}
.container div {
  position: absolute;
  height: 5px;
  border-radius: 5px;
  background-color: red;
  transform-origin: bottom left;
}
.shine1 {
  width: 26px;
  transform: rotate(-95deg) translate(20px, 5px);
}
.shine2 {
  width: 32px;
  transform: rotate(-45deg) translate(20px);
}
.shine3 {
  width: 26px;
  transform: rotate(0deg) translate(15px);
}

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

Utilizing MongoDB's object within the mapper function in MapReduce

I have a question about querying data in MongoDB using the aggregate framework. Originally, my data was structured like this: [ { created_at: "2014-03-31T22:30:48.000Z", id: 450762158586880000, _id: "5339ec9808eb125965f2eae1" } ] Now, ...

The Electron React app crashes due to difficulty parsing the source map

I'm a beginner in the coding world and currently working on creating an electron app using react. One of the functionalities I want to implement in the app is the ability to save user login information so that the data can be automatically fetched whe ...

What is the origin of the second parameter in an arrow function that returns another arrow function in a React component with Redux?

I'm having trouble understanding where the (val) parameter is coming from in the returned arrow function. I understand that max/minLength is an arrow function taking an argument set on the input field (3 and 25), and it returns another arrow function ...

Adding CSS3 animation to a button to enhance its appearance when its icon undergoes a transformation

I'm working on implementing a CSS transition for a button that changes when the font-awesome icon inside the button is replaced with another using jQuery. Here is my HTML code for better understanding: <button type="button" class="navbar-tog ...

The Vuetify Jest button trigger fails to function properly despite utilizing a spy

Recently delved into the world of Vue.js and Jest to see how they interact. I watched some tutorials and then decided to give it a go myself, but ran into trouble with getting the trigger click to work. Within my component, I have a login button, which is ...

Extracting Text from a Span Element Using XPath in Selenium

Here is the HTML code snippet: <div class="a-row a-spacing-small a-size-small"> <div class="a-row"> <a class="a-link-normal a-declarative g-visible-js reviewStarsPopoverLink" href="#" data-action="a-popover" data-a-popover="{"closeButton":" ...

Enhance HTML Performance with Resource Preloading

Just a quick query I wanted to throw out there - would prefetching resources like js scripts and images actually slow down the page load time? For instance, let's say I have a page with several links such as: <link rel="prefetch" href="http://exa ...

Alter the background color of the entire document to (EDIT) in the top dialog box

<script> $(function() { $( "#dialog" ).dialog(); }); </script> </head> <body> <div id="dialog" title="Basic dialog"> <p>This default dialog box can display information. It can be moved, re-sized, and closed ...

Maintain the HTML font color when printing - Issue with IE settings, not the printer

I've been struggling with this issue all day. Initially, I thought it was a problem with the print settings, but then I realized that it's actually the "Print background colors and images" option in IE causing the trouble. Here is the last test ...

Utilize IntelliJ's TypeScript/JavaScript feature to extract a method from all instances

I am relatively new to using IntelliJ Idea Ultimate 2020 and I am currently exploring the refactoring functionalities within the software. Is there a way to extract a method from a section of code and apply it to all instances easily and exclusively withi ...

What is the best way to activate a function within an npm package in a Vue application?

I'm just starting out with Vuejs and I've recently installed the vue-countup-v2 npm package. I successfully imported it into my Vue component and noticed that it works perfectly when the page loads. However, I am interested in triggering the Coun ...

I'm having trouble with the routing of a Node.js REST API built with Express and Mongoose

I am currently in the process of constructing a RESTful webservice by following a tutorial that can be found at: However, I have encountered an issue where it is returning a CANNOT GET/ reports error. Despite my efforts to troubleshoot and rectify the pro ...

What is the reasoning behind next.js requiring the use of modular CSS instead of a global stylesheet linked to each page?

I am currently attempting to include a minified link stylesheet created with sass:watch into a particular page of a next.js (13) project. However, upon adding it using the head component, I received this warning: Do not add stylesheets using next/head I ...

Implementing a jQuery plugin and AngularJS for post-render actions

I am currently in the process of developing a slider, where I am utilizing the ng-repeat directive to loop through a (RESTful) service and generate slides for the slider. For proper initialization, I have enclosed the slider within a custom directive that ...

Is there a way in Vue to switch between encrypted and unencrypted content in an input field?

I'm grappling with the challenge of creating an input field where the contents are initially hidden as 'ab****gh' and can be toggled to reveal as 'abcdefgh' upon a click. I've been experimenting with some code, but I'm st ...

Issues with undesirable spacing in CSS using the display property and table-cell display type

Having trouble grasping the concept of table and table-cell in css? See this example: http://jsfiddle.net/dd7h7/3/. HTML <div class="widget"> <div class="button"> <div class="content"> <div class="icon">A</div> ...

Update the font style of the navigation bar

Hey there! I recently downloaded a template from this website: . However, I'm facing an issue with the nav bar displaying strange fonts when using Vietnamese letters. For example, "Nước" shows up as all uppercase and the letters "uo" are shortened. ...

Issue with the Animated Skill Bar not functioning properly when scrolling

I've been trying to implement an animated skill bar in my Portfolio using JQuery, but I'm facing some challenges. Despite following various tutorials, the code doesn't seem to work as expected. I've tried calculating section scroll posi ...

Add a variety of images

Looking for help with uploading multiple images to a folder and saving paths in the database? Here's a code snippet I've been working on: The issue I'm facing is that while the image names are being saved in the database, the actual images ...

Is it possible to create a hyperlink in the <button> element?

Having been immersed in HTML5 for quite a while now, I recently encountered a challenge while working on my login/register page project. I wanted to create a button that would redirect me to another HTML page upon clicking. While I am familiar with the < ...