Insert an icon at the conclusion of a truncated multi-line text without causing a line break

I have a specific requirement where I am looking to present two lines of text, followed by an icon displayed through an img tag. If the text exceeds two lines, I want to display an ellipsis. However, it is crucial that the icon remains inline with the text and is not clipped if the length of the text increases.

The desired outcome should resemble:

A lengthy text that
spans two lin.. 🙂

For this example, let's consider the emoji as an img tag

Place icon after a line with text-overflow ellipsis

When dealing with a single line of text, utilizing inline-block as recommended in the stack overflow thread above works perfectly. However, when attempting to apply this to multiline text, it doesn't have the desired effect.

display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
-moz-box-orient: vertical;

https://codepen.io/praneethack/pen/LYxxPGN

Edit: I have made adjustments to the code on CodePen to include an img tag instead of a font icon

Answer â„–1

Give this a try!

.title {
  text-overflow: ellipsis;
  overflow: hidden;
  display: inline-block;
  width: 200px;
  vertical-align: middle;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  -moz-box-orient: vertical;
  border: 1px solid #333;
  font-size: 1em; /* Set font size to 1em */
  max-height: calc(2em + 5px); /* Set maximum height for two rows */
}

I removed the white space value and added a font size of 1em for better readability.

Then I set a max height of 2em to display a maximum of two rows of text.

UPDATE I initially overlooked the image aspect.

Here's an improved solution

.title {
  text-overflow: ellipsis;
  overflow: hidden;
  display: inline-block;
  width: 200px;
  vertical-align: middle;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  -moz-box-orient: vertical;
  font-size: 1em;
  max-height: calc(2em + 5px);
  position: relative;
  border: 1px solid #333;
}

.icon {
  width: 15px;
  position: absolute;
  bottom: 0;
  right: 0;
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet" />
<span>
  <span class="title">
    <img class="icon" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSBdJ13-QNu7aJefmbaMMuY6ngaEbGWXaf6Ag&usqp=CAU"/>
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim.
  </span>
</span>

The image is placed inside the span element which needs to appear before the text content.

Answer â„–2

Two elements are essential for achieving this effect:

The first element, which is an icon, should be positioned as the initial child of the text container. It remains visible only when the text is truncated. The second element, which is the same icon, should be positioned at the end. Consequently, it will not be displayed if the text is truncated and does not fit the height of its container.

By using JavaScript to detect truncation of the text, the first icon element will be hidden when the text fits within the container and is not truncated.

It is worth mentioning the utilization of a --line-clamp CSS variable for both the line-clamp property value and the ::before pseudo-element. This "pseudo-floated" element assists in positioning the first icon element at the end of the text when it's truncated.

This example supports horizontal resizing:

function checkTruncation( element ){ 
  const truncatedText = element.scrollHeight > element.clientHeight
  element.classList.toggle('truncated', truncatedText)
}

// observe resize changes
const resizeObserver = new ResizeObserver(m => checkTruncation(m[0].target))

resizeObserver.observe(document.querySelector('p'), { attributes: true })
p {
  --line-clamp: 4;
  
  display: -webkit-box;
  -webkit-line-clamp: var(--line-clamp);
  -webkit-box-orient: vertical;
  
  width: clamp(300px, 50%, 900px);
  resize: horizontal;
  overflow: hidden;
}

p::before {
  content: '';
  float: right;
  height: calc((var(--line-clamp) - 1) * 1lh);
}

p .icon:first-child {
  clear: both;
  float: right;
}

/* 
  hide the "show more" link if 
  the text is fully visible and not truncated
*/
p:not(.truncated) .icon:first-child {
  display: none;
}
<p>
  <span class='icon'>😀</span>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit, 
  sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 
  Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris 
  nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in 
  reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
  <span class='icon'>😀</span>
</p>

Answer â„–3

One way to position an icon next to ellipsis is by using the :before pseudo-element:

.foo {
  position: relative;
  display: -webkit-box;
  max-width: 200px;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
  color: black;
}


.foo:after {
  content: "... \f015";
  display: inline-block;
  font: normal normal normal 14px/1 FontAwesome;
  font-size: inherit;
  text-rendering: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  position: absolute;
  top: 88%;
  right: 0;
  transform: translateY(-50%);
  background: #fff;
  padding: 0 2px 0 0;
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet" />

<div class="foo">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim.</div>

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

Tips for employing the slice approach in a data-table utilizing Vue

I have a unique situation in my Vue app where I'm utilizing v-data table. The current display of data in the table works fine, but I now want to enhance it by incorporating the slice method. Here is the current data displayed in the table: https://i ...

Does the a:hover:not() exception only apply to elements with the .active class?

I developed a navigation bar and split it into 3 distinct sections: 1. id="menu" 2. id="fake" (button to fill space) 3. id="social" My main goal is to exclude the .active page and the fake button from the hover effect, but it seems that using a:hover:not( ...

Avoiding the insertion of duplicates in Angular 2 with Observables

My current issue involves a growing array each time I submit a post. It seems like the problem lies within the second observable where the user object gets updated with a new timestamp after each post submission. I have attempted to prevent duplicate entr ...

What causes the HTML element's X position value to double when its X position is updated after the drag release event in Angular's CDK drag-drop feature?

I am facing a challenge with an HTML element that has dual roles: Automatically moving to the positive x-level whenever an Obsarbalve emits a new value. Moving manually to both positive and negative x-levels by dragging and dropping it. The manual drag a ...

Running two blocks of scripts (utilizing lab.js as a loading manager)

I am currently facing an issue where I am trying to load two separate blocks of `lab.js` in different locations. However, when I attempt to utilize functions from the second block that are called from files loaded in the first block, they are showing as un ...

broken alignment of right-aligned Bootstrap navbar

I need help with displaying a navbar on my webpage. I want the right side of the navbar to show different elements based on whether the user is logged in or not. If the user is not logged in, it should display "Login" and "Register," and if they are logged ...

Tips for utilizing an npm package in conjunction with Hugo

I created a basic hugo site with the following command: hugo new site quickstart Within the layouts/_default/baseof.html file, I have included a JavaScript file named script.js. Inside script.js, the code looks like this: import $ from 'jquery' ...

Mastering the art of using transitions in conjunction with display properties

I'm trying to achieve a fade-in effect with the CSS property display:block. Here's my HTML code: <div>Fade</div> And here's my CSS code: div { display: none; transition: 2s; } div:hover { display: block; } Unfortunately, thi ...

Strengthening JavaScript Security

Throughout the past few years, I have delved into various javascript libraries like Raphael.js and D3, experimenting with animations sourced from different corners of the internet for my own learning. I've obtained code snippets from Git repositories ...

How can I determine the mouse's location relative to the bottom right corner of the

Currently, I am in the process of writing jQuery code that will detect if the mouse is positioned near the bottom or right side of a window, and then adjust the tooltip's position accordingly. This becomes crucial because the table in which these tool ...

Methods for submitting POST requests with key data enclosed in quotation marks?

Upon investigation, I discovered that the Request Payload object's key does not have quotation marks as shown below. https://i.sstatic.net/U54V9.png However, I am interested in sending a request with keys that are marked with quotations. Interestingl ...

How to Generate an Array of JSON Objects in JavaScript on a Razor Page using a Custom ViewModel in MVC?

Attempting to populate the array within my script for future charting with D3.JS, I came across some issues. Following advice from this post, I used a specific syntax that unfortunately resulted in an error stating "Uncaught ReferenceError: WebSite is not ...

HTML/CSS: Maintain Hover-Over Pop Up Boxes in Position Until Another Element is Hovered Over

Seeking HTML code to maintain a hover-over pop-up box in position on an image map until another section of the image map is hovered over. For example, refer to my code below - when hovering over a country on the map, a pop-up box with information about a ...

Implementing Jquery Table Selection with Custom CSS Class

When I attempted to use the selectable feature on a table with a CSS class applied, the selection did not work. However, when I removed the CSS class, the selection worked perfectly fine. I suspect that the issue lies within the CSS definition, but I' ...

Encountering issues with the Justify props in Material UI grid – how to troubleshoot and solve the problem

Can someone help me troubleshoot why justify is not working in this code block? <Grid container direction='column' alignItems='center' justify='center' spacing='1'> <Grid item xs={12}> <Ty ...

Updating a session or global variable cannot be read by an AJAX request

Currently using Flask with google-python-api-client for fetching data from Youtube. Experimenting with loading the next video asynchronously from the playlist upon button click. To achieve this, setting the nextPageToken parameter in the request is essent ...

Launching a React build using Docker on Apache or AWS

I am a beginner to the world of docker and react. My goal is to successfully deploy a production build on AWS. Here are the steps I have taken so far: Created a dockerfile. Built and ran it on the server. npm run and npm run build commands are functionin ...

Various image resolutions designed for extra small, small, medium, and large screens

My image has a relative width and currently the src points to a single, large file (approximately 1000px). The issue arises on small devices with Opera and IE where the browser scaling results in pixelated images. Conversely, using a smaller image leads to ...

Using a ternary condition within the ngClick directive

Trying to implement different functionalities based on the type of device. The setting tab is clickable, and in the desktop version, clicking should redirect to a default URL. However, on mobile devices, clicking the same link should open a modal window. ...

The module located at "c:/Users//Desktop/iooioi/src/main/webapp/node_modules/rxjs/Rx" does not have a default export available

I am currently delving into the realm of RxJs. Even after installing rxjs in package.json, why am I still encountering an error that says [ts] Module '"c:/Users//Desktop/iooioi/src/main/webapp/node_modules/rxjs/Rx"' has no default export ...