What is the best way to achieve an ellipsis-like effect for non-string elements while limiting the number of rows to a maximum of 2?

The objective is to achieve the following:

https://i.sstatic.net/lcChx.png

However, the challenge lies in adding two "hardcoded" elements at the end of row 2:

  • The "# more" button (only when necessary)
  • The "face-plus" button (always)

This pertains to the "ellipsis" effect that I am seeking to implement.

I have experimented with the code below:

// HTML
<div class="container">
  <div class="children">
    Hola1
  </div>
   <div class="children">
    Hola2
  </div>
   <div class="children">
    Hola3
  </div>
    <div class="children">
    Hola4
  </div>
   <div class="children">
    Hola5
  </div>
   <div class="children">
    Hola6
  </div>
</div>

// css
.container {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: flex-start;
  width: 150px;
  border: 1px solid black;
  padding: 5px;
  height: 80px; // this makes the trick of having 2 rows
  overflow: hidden; // this makes the trick of having 2 rows
}

.children {
  border: 1px solid black;
  margin: 5px;
  padding: 5px;
}

The result I achieved was as follows:

https://i.sstatic.net/3CDOo.png

Nevertheless, I am facing difficulties in appending the "fixed" elements at the end of row 2 due to other concealed elements in the list.

Several key considerations include:

  • The element widths are variable.
  • A maximum of 2 rows should be displayed.
  • By the end of row 2, the "# more" button and face icon must be present (with the former only appearing if necessary).

Your assistance is greatly appreciated

Answer №1

To simplify the process and avoid tedious arithmetic, consider clearing the container and adding elements one by one. Check if the newly added element (along with its 'more' element and icon) exceeds the bottom of the container.

If it does exceed the bottom, go back one step to ensure the correct placement of the 'more' statement.

It's unclear whether you intended to include the 'more' statement and icon in the DOM or left space for them through a pseudo element. This snippet adds them to the DOM so you can interact with the 'more' element as needed.

Remember to run this code on every load and resize event.

const container = document.querySelector('.container');
container.style.visibility = 'hidden'; //to prevent flashing as elements are added
const cbottom = container.getBoundingClientRect().bottom;
const children = document.querySelectorAll('.children');
const num = children.length;

container.innerHTML = '<div class="moreEl"><span class="remainder">xxx</span> MORE</div><img src="youricon.jpg" style="width: 20px; aspect-ratio: 1 / 1;">';
const moreEl = container.querySelector('.moreEl');
const remainder = moreEl.querySelector('span');

// add each child individually with the 'nn more' plus icon until reaching the container limit
let i = 0;
for (i; i < children.length; i++) {
  remainder.innerHTML = num - i - 1;
  container.insertBefore(children[i], moreEl);

  if ((children[i].getBoundingClientRect().top > cbottom) || (moreEl.getBoundingClientRect().top >= cbottom)) {
    children[i].parentElement.removeChild(children[i]);
    remainder.innerHTML = num - i;
    break;
  }
}

if (i >= (num - 1)) {
  moreEl.parentElement.removeChild(moreEl);
} else {
  for (let j = i; j < num; j++) {
    container.append(children[j]);
  }
}
container.style.visibility = 'visible';
* {
  box-sizing: border-box;
}

.container {
  visibility: hidden;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: flex-start;
  width: 150px;
  border: 1px solid black;
  padding: 5px;
  height: 80px;
  overflow: hidden;
}

.children {
  border: 1px solid black;
  margin: 5px;
  padding: 5px;
}

.moreEl {
  padding: 10px;
}
<div class="container">
  <div class="children">
    Hola1
  </div>
  <div class="children">
    Hola2
  </div>
  <div class="children">
    Hola3
  </div>
  <div class="children">
    Hola4
  </div>
  <div class="children">
    Hola5
  </div>
  <div class="children">
    Hola6
  </div>
  <div class="children">
    Hola7
  </div>
  <div class="children">
    Hola8
  </div>
  <div class="children">
    Hola9
  </div>
  <div class="children">
    Hola10
  </div>
</div>

Note: The 'Hola' elements in this snippet make it easier to test different container widths.

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

What could be causing the CSS loader in webpack to malfunction?

I am currently working on implementing the toy example mentioned in the css-loader documentation which can be found at https://github.com/webpack-contrib/css-loader Additionally, I have also followed a basic guide that recommends similar steps: https://cs ...

Mobile Device Centering Problem with Bootstrap Cards

Despite my thorough research efforts, I have been unable to find a solution. The code snippet below is meant to display the image provided, but it seems to shift to the left when viewed on a mobile device. If anyone can assist me with this issue, I would ...

Utilizing the Autocomplete feature of Material-UI in conjunction with Formik for enhanced form functionality

Attempting to integrate Formik with Material UI's Autocomplete component has been a bit challenging. While other Material-UI components like text fields and selects work smoothly with Formik, implementing Autocomplete is proving to be more difficult. ...

Brick-themed HTML/CSS elements drift away from each other

I'm currently designing an image collage for my website and attempted to use masonry for the layout. However, when I adjust the size of the blocks, they seem to drift apart, creating large gaps between each block. Any suggestions on how to resolve thi ...

``There seems to be a problem with navigating to a specific

I'm encountering an issue with this script // App.js ( shrink ) var controller = require('./controller'); app.get('/', controller.index); app.get('/home', controller.home); // /controller/index.js var meta = { ...

How can we maintain focus on a controlled TextField while making sure to update the state as needed?

How can I update the value of a controlled Material-UI TextField component without losing focus? The value is currently set based on the parent component's state, but I want it to update dynamically. Any assistance would be greatly appreciated. export ...

Apply the animate.css classes before removing the element

I'm struggling to add and remove CSS classes on my label/checkbox tick, as well as removing the item once it's been checked. I can only manage to do one of these tasks at a time. $(function () { $("label[for='<%= @todo.id %>' ...

positioning three background images in the same place

I have three images img1.png, img2.png, img3.png with heights 600px,400px and 200px respectively. My goal is to position these images in a specific order: img1.png in the back, img2.png in the middle, and img3.png in the front. I attempted to use CSS posit ...

Specifying the type of a React class component with static props - A guide on defining the prop

Let's imagine we have a straightforward React component with a constant property named meta as shown below: // RectTool.tsx class Rect extends React.PureComponent static meta = { icon: <AnotherComponent />, initial: { ...

What is the best way to change the active class using jquery?

Excuse me, can I get some help? I'm still learning html and jquery, and I've seen this question asked before, but none of the solutions seem to work for me. I'm trying to change the active class in my navbar when I click on another link. Wh ...

Unable to hide jQuery form and receiving undefined function output

I seem to be facing an issue with one of the buttons. It's not functioning properly. Whenever I click on the "Add Run" button followed by the "Home" button, most functions stop working as expected. The dynamically created form doesn't hide, the ...

Side panels positioned on both the left and right sides of an OpenLayers map in the center

I am in the process of creating an interactive game map using the powerful OpenLayers 3 API. My goal is to incorporate four panels into the layout - two on each side (right & left) with the map displayed in the center, positioned below the side panels. How ...

The Ajax form is failing to send data to PHP

Thanks to Stackoverflow, I've been diving into website design. I recently put together some code for handling data sent from an HTML form using Ajax. The code does a good job of error checking, but it seems to be missing the step of actually sending t ...

Is the navigation bar offset causing an issue?

After struggling with my navigation menu in Google Chrome, I finally found a solution. However, the nav bar is now offset on one page but not on another. For the aligned main site view, visit , and for the left-offset forum view, visit . This is the HTML ...

Can you outline the key distinctions between ref and reactive in Vue.js?

After diving into Vue.js recently, I'm finding myself struggling to completely understand the key distinctions between using ref and reactive. Can someone clarify when it's appropriate to utilize ref versus reactive? ...

What is the process for adding a new item each time the button is clicked?

I am working on an application that includes two select dropdowns followed by a button below them. .component.html <div class="row"> <div class="col-sm-5"> <select class="form-control whenI&quo ...

The import Alias was not recognized by the React Jest test

I'm struggling with a React Jest test for a Button component where an import is not recognized. Can anyone suggest why the test is failing to recognize this import? Component: import ... import ... from 'styled-components'; import ... from ...

Is there a way to retrieve JSON data with form.submit()?

Greetings, I have successfully submitted a form from jQuery using the following code: $('#form').submit(); The form is successfully submitted to the server. However, I am looking to return JSON data from the post request so that I can dynami ...

What is the best way to increase the size of the input field to allow for more typing space?

My query is quite simple. Even when I set the height to 100px, the cursor still starts in the middle of the input box. I want the entire box to be utilized with the cursor starting at the top left corner for a more intuitive paragraph writing experience. ...

A guide on implementing a confirmation box with jquery confirm plugin for form submission

After submitting a form, I want to display a confirmation message without using the typical method of "return confirm("Are You Sure?")". I decided to utilize JQuery Confirm in this way: @using (@Html.BeginForm("SubmitTest", "HydrostaticReception", FormMe ...