What is the best way to shorten text in React/CSS or Material UI based on the line height multiples?

I'm facing an issue with creating a Material UI card that contains text. My goal is to set a fixed height for the card and truncate the text if it exceeds 3 lines. Can anyone suggest the best approach to achieve this?

Here's the code snippet I've been working on. I attempted using CSS to truncate the text, but I encountered two problems: the ellipsis doesn't display, and the overflow cuts off the text horizontally. Ideally, I'd like to set the truncation based on multiples of the line height rather than in pixels. Additionally, I need it to still function properly when the screen size changes.

import React from 'react';

// Material UI
import {
  Card,
  CardActionArea,
  CardContent,
  CardMedia,
  makeStyles,
  Typography,
} from '@material-ui/core';

const useStyles = makeStyles(theme => ({
  media: {
    height: 140,
  },
  title: {
    height: 50,
    overflow: 'hidden',
    textOverflow: 'ellipsis',
  },  
  description: {
    height: 50,
    overflow: 'hidden',
    textOverflow: 'ellipsis',
  },
}));

const ContentThumbnail = ({ image, title, description, date }) => {
  const classes = useStyles();
  return (
    <Card>
      <CardActionArea>
        <CardMedia
          image={image}
          title=""
          className={classes.media}
        />
        <CardContent>
          <Typography gutterBottom variant="h5" component="h2" className={classes.title}>
            {title}
          </Typography>
          <Typography variant="body2" component="p" className={classes.description}>
            {description}
          </Typography>
        </CardContent>
      </CardActionArea>
    </Card>
  );
};


export default ContentThumbnail;

Answer №1

Unfortunately, adding ellipsis to multiple lines is not possible as it can only be applied to a single horizontal line.

A workaround would be to calculate the total number of symbols allowed before displaying the ellipsis.

In your code you could do something like this:

const [description, setDescription] = useState('');
const MAX_SYMBOLS_ALLOWED = 50;

useEffect(() => {
  if(description.length >= MAX_SYMBOLS_ALLOWED) {
    // Subtracting 2 for the 3 dots in the ellipsis
    const transformed = description.substr(0, MAX_SYMBOLS_ALLOWED - 2);

    setDescription(`${transformed}...`)
  }

}, [description])
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.1/umd/react-dom.production.min.js"></script>

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

`In TypeScript Angular, encountering challenges with accessing object properties`

My TypeScript object looks like this const playlist: { tracks: Array<Track> } = { tracks: new Array<Track>() }; This is the Track interface I am working with interface Track { title?: string; album?: string; artists?: string; duration? ...

Achieving multiple validations on a single element in AngularJS, along with the ability to validate

Currently, I am in the process of constructing a form and utilizing the built-in AngularJS validation objects to validate the form. The following is an overview of my form: <form name="myForm" ng-submit="DoSomething()" novalidate> <te ...

Inline CSS alignment

While experimenting with layout inline elements, I came across some unusual behavior. Can someone please explain why there is a difference? I have applied the following CSS to both HTML structures: .time { position: relative; top:100px; heigh ...

Utilizing Bootstrap 4 to ensure the final DIV is vertically stacked and fills the remaining space in the container

Having trouble creating a responsive layout using Bootstrap 4? Specifically, when two divs wrap vertically on smaller devices, the top div pushes the lower div down, exceeding the parent container. I want the lower div to fit within the container. How can ...

What steps can I take to avoid encountering this endless loop?

When passing foo in the arguments of useEffect to use existing array values, it causes an infinite loop because setting new values triggers the f() function again. How can this be resolved? An example of imaginary code is: const [foo, setFoo] = useState&l ...

Wordpress multisite facing API CORS problem due to header settings within theme version 5

I am encountering an issue with my React app that interacts with a Wordpress v5 API. const api = `${WAPI}`; const headers = { 'Content-Type': 'application/json' } ; fetch(api, { headers: headers }) .then(function(data){ console ...

Exploring the interactive doughnut graph using SVG and Vue.js

Looking to create a unique dynamic donut chart using SVG and Vue. I want it to mirror the exact SVG format found on this webpage: (To see the animated chart, select a dish and click on ingredients) This might not have been the best approach, but it was ...

Activate button through input using Bootstrap

I am struggling to achieve the desired functionality with my "sendit" button. I want it to be enabled as soon as there are any characters entered in the box, but I have tried multiple solutions without success. Part of HTML: <input type="password ...

The issue with the antd Input component's onChange event not updating state correctly when using a list fetched from an axios get request in a React

Recently delving into React, I've dedicated the past week to honing my skills. My current project involves creating a straightforward application featuring a 'product create' form alongside a product list equipped with a search bar (utilizin ...

Do these exports serve the same purpose?

Can someone help me understand why one export works while the other doesn't? I've tried to figure it out on my own but I'm stuck. Functioning Example const dataStore = new Vapi({ baseURL: 'http://domain.test/api', state: ...

SignalR 2.2 users are experiencing a lack of message reception

I have developed a unique self-hosted SignalR application that is operating within the framework of a console application. To access the hubs within this application, I have implemented a wrapper class to avoid referencing the SignalR.Core assemblies direc ...

Angular Material Flex is not providing the correct size

There seems to be a problem with certain values for setting the flex property in the Angular Material layout library. The issue is clearly demonstrated in this straightforward example. By clicking through, you can observe that some values display correctl ...

Incorporating a delay into looped HTTP requests while effectively utilizing Promise.all to track their completion

Greetings! In my current project, I am trying to introduce a 50ms delay before each subsequent HTTP request is sent to the server. Additionally, I aim to incorporate a functionality that triggers after all requests have been successfully made. To better e ...

Utilizing jQuery to implement a function on every individual row within a table

I have a collection of objects that requires applying a function to each item, along with logging the corresponding name and id. Below is the snippet of my code: var userJson = [ { id: 1, name: "Jon", age: 20 }, { ...

A more concise approach to crafting ajax requests

Lately, I've been immersed in building various web applications using php, mysql, jquery, and bootstrap. Now, I'm faced with a common issue - how to streamline my ajax queries for posting data? Writing code that is not only functional but also a ...

Troubleshooting a problem with CSS Matrix animations

Lately, I've been working on creating some matrix animations. However, I noticed an unusual issue. The code below seems to function differently across Firefox, Safari, and Chrome: @-moz-keyframes matrix { from { -moz-transform: matri ...

Struggling to locate the correct path for the CSS file in Express and Handlebars

As part of a student exercise, I am attempting to access an API containing information about presidents and style them using CSS. However, I am facing issues with linking the style.css file. I have tried various methods to change the path and public path ...

The use of the .reset() function in typescript to clear form data may lead to unexpected

I've been trying to use document.getelementbyID().reset(); to reset form values, but I keep running into an error in TypeScript. Property 'reset' does not exist on type 'HTMLElement'. Here's how I implemented it: const resetB ...

"Enhancing the aesthetics: Stylish blue borders around Bootstrap

After successfully setting up bootstrap-select, I have noticed that blue borders are showing in two specific instances: 1) within the dropdown menu 2) when a new value is selected I have made some adjustments but the issue persists. Can someone please p ...

Load a script in a specific div using React

Can anyone assist me with loading a script onto a specific component in my React application? Here is the script that needs to be loaded at the bottom-most div within my component: <div id="rexxxx"></div> <script> new carouselI ...