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

Issue with updating bound property correctly when dynamically generating components using v-for in Vue.js

Encountered a challenge with vue.js and seeking guidance on the best approach to address it. Here's a concise summary of the issue: Situation Data is fetched from a rest API, handled by a class called DataLoader using javascript prototype syntax. Th ...

Having trouble with the animate() function not working properly?

I have been working on the following code snippet: var isOn = false; $('.switch').on("click",function(){ if (isOn){ $('.toggle').animate({ left:"18px" },10,"linear", { complete: function(){ $(&ap ...

Flick user media cards left or right to uncover the following one

I am currently working on creating a widget that will display user media objects in a horizontal layout using ng-repeat. The goal is to allow users to swipe left or right to reveal the next media card, similar to the image shown below. In the example, you ...

Submitting a form and obtaining results without relying on jQuery

Finding information on how to accomplish this task without using jQuery has proven to be a challenge. It seems like everyone is pushing for jQuery for even the simplest tasks nowadays. Despite avoiding unnecessary use of jQuery in creating a rich experienc ...

React.js encountered a SyntaxError stating "Unexpected character at line 1 column 1 of the JSON data during JSON.parse" operation

*I am currently working on a project where login and protected pages are involved. Upon logging in, a token is generated which allows access to the dashboard page. However, I have encountered an error message stating "SyntaxError: JSON.parse: unexpected ch ...

Obtain data with matching JSON values in a REACT application

Recently, I received a JSON file that looks something like this: [ { "symbol": "A", "name": "Agilent Technologies Inc", "exchange": "NYSE", }, { "symbol": "AAC ...

Why is it that methods lose their binding when they are returned from a ternary operator?

class TestClass { constructor() { this.prop = 5; } MethA() { console.log(this); console.log(this.prop); } MethB() { (true ? this.MethA : null)(); } } Test = new TestClass(); Test.MethB(); What is the ...

Navigating from an AngularJS page to a ReactJS page on separate ports: A quick guide

I am currently working on an application with a landing page built using AngularJS. The login functionality is also AngularJS-based, and after a successful login, the user's token needs to be stored in local storage and then redirected to the landing ...

The issue with Next.js is that cookies are not being transmitted along with fetch requests, even when credentials are

I've been developing a Next.js application that originally started as a regular React app created using create-react-app. I'm facing an issue where the cookies are not being sent with my fetch request to the server, despite setting credentials: & ...

Switching an :active class using ReactJS

Currently, I am working on creating an onboarding screen where the user is required to select three or more items. Once the user clicks on an item, a purple overlay should remain visible. For reference, this is what I have in mind: Sharing my code snippe ...

Leveraging mergeProps for accessing state within mapDispatchToProps

From what I've gathered, in order to access state that's been loaded in one dispatch handler from other dispatch handlers, the best approach is to utilize mergeProps as suggested in this informative article. I've encountered an issue with t ...

A distinctive noise is heard when hovering over multiple instances of a div

I'm trying to implement a feature where a unique sound plays when hovering over a specific div element with a particular class (.trigger). However, I am encountering an issue where multiple instances of this div class result in the same sound being pl ...

How can we effectively manage error responses and retry a failed call in NodeJS without getting tangled in callback hell?

I am in search of an effective approach to handle the given situation. I am curious if employing promises would be a helpful solution? Situation Overview: When a call retrieves a callback, and this callback receives an error object as a parameter. My obj ...

conceal elements using the <option> class隐藏

Although it seems like a simple task, I'm struggling to make it work. I created a form where the user can select a month from a list using the tags: <select> <option> When the selection is changed, the class .gone from the day SELECT is ...

Using the calc function to define input width may not yield the expected results

I am facing an issue where I have an input element with width: calc(100% - 100px); and no padding/margin/border. Next to this input, I want to place a div with position: inline-block; and width: 100px;. The problem is that the div is going to the next lin ...

Unexpected TypeError occurred when trying to Fetch data from an Express Server hosted on Window object

Error Message : Uncaught (in promise) TypeError: Failed to execute 'fetch' on 'Window': Invalid name Feeling stuck as I looked around, unsure of what's causing this issue. My goal is to develop a website that can eventually make a ...

Encountering a Typescript error while attempting to extract state from a History object containing an enum property

My enum structure is as follows: enum values { first, second, } Within my component, I handle the history object like this: const { push, location: { state = {} } } = useHistory(); Additionally, in the same component within a useEffect hook, I have ...

Is the child constantly updating due to a function call?

Having difficulty navigating the intricacies where a child keeps re-rendering due to passing a function from the parent, which in turn references an editor's value in draftjs. function Parent() { const [doSomethingValue, setDoSomethingValue] = Re ...

Line breaking by syllables using CSS

When it comes to CSS properties, the word-break attribute is able to split words across lines at specific points (such as the first character extending beyond a certain length). Surprisingly, there seems to be no existing CSS method (even with limited supp ...

Retrieving information from Flask server using an Ajax request

Exploring Flask and Ajax, my server-side web application is meant to double and return a passed number. I adapted the code from the example on Flask's site, resulting in this Python snippet: from flask import Flask, request, jsonify # Initialize the ...