Only implement the CSS styles if there are multiple elements that have the same class

I have 2 cards with the class card displayed within a card-stack. There can be any number of such cards.

<div class="card-stack">
  <div class="clear"><button name="clear" value="Clear all" onclick="removeAllCards(this)">Clear All</button></div>
  <div class="card" style="--y:1" onclick="remove(this)">
    <div class="card-header">
      <div class="card-avatar">
        <img src="https://static.thenounproject.com/png/363633-200.png">
      </div>
      <div class="card-title">Announcement 1</div>
    </div>
    <div class="card-body">
      This is announcement 1.
    </div>
  </div>
  <div class="card" style="--y:2" onclick="remove(this)">
    <div class="card-header">
      <div class="card-avatar">
        <img src="https://static.thenounproject.com/png/363633-200.png">
      </div>
      <div class="card-title">Announcement 1</div>
    </div>
    <div class="card-body">
      This is announcement 1.
    </div>
  </div>
</div>

When hovering on the card-stack, CSS is applied to each card

.card-stack:hover .card{
  transform: translateY(calc((var(--y) * -105% + 200px)));
  box-shadow: none;
}

I want the HOVER effect to apply only if there are more than one elements with the class card. How can this be achieved using CSS?

CodePen link for the snippet above

function remove(element) {
  element.remove();
}

function removeAllCards(element) {
  element.remove();
  document.querySelectorAll(".card").forEach(el => el.remove());
}
body {
  background-color: #e8eaed;
}

.card {
  width: 300px;
  min-height: 150px;
  background-color: white;
  position: fixed;
  top: 75vh;
  right: 100px;
  transform: translate(-50%, -50%);
  display: grid;
  border-radius: 5px;
  font-family: sans-serif;
  font-size: 14px;
  color: #00000080;
  box-shadow: 0 5px 15px 0 #00000040, 0 5px 5px 0#00000020;
  transition: transform 200ms;
  padding:15px;
  cursor:pointer;
}

.card {
  transform: translateY(calc((var(--y) * 20px) - 50%)) scale(calc(1.0 + var(--y) * 0.05));
}

.card-avatar {
  display:block;
}
.card-avatar img {
  width:40px;
  height:40px;
  float:left;
}
.card-title {
  font-size:16px;
  display:inline-block;
  margin-top:10px;
  margin-left:10px;
}

.card-header {
  height:30px;
  display: inline-block;
}
.card-body {
  margin-top:-30px;
}

.card-stack:hover .card{
  transform: translateY(calc((var(--y) * -105% + 200px)));
  box-shadow: none;
}

.card-stack:hover .clear {
  visibility: visible;
  transform: translateY(calc((var(--y) * -105% + 200px)));
  position:absolute;
  top:2vh;
  right:40px;
}

.card-stack {
  position:fixed;
  width: 400px;
  min-height: 100vh;
  position: fixed;
  right: 65px;
}

.clear {
  visibility:hidden;
}
<div class="card-stack">
  <div class="clear"><button name="clear" value="Clear all" onclick="removeAllCards(this)">Clear All</button></div>
  <div class="card" style="--y:1" onclick="remove(this)">
    <div class="card-header">
      <div class="card-avatar">
        <img src="https://static.thenounproject.com/png/363633-200.png">
      </div>
      <div class="card-title">Announcement 1</div>
    </div>
    <div class="card-body">
      This is announcement 1.
    </div>
  </div>
  <div class="card" style="--y:2" onclick="remove(this)">
    <div class="card-header">
      <div class="card-avatar">
        <img src="https://static.thenounproject.com/png/363633-200.png">
      </div>
      <div class="card-title">Announcement 1</div>
    </div>
    <div class="card-body">
      This is announcement 1.
    </div>
  </div>
</div>

Answer №1

One interesting approach could be to style elements that are both the first and last child of their parent simultaneously.

.myClass {
  color: tomato;
}

.myClass:first-child:last-child {
  color: DarkSlateGrey;
}
<div>
  <span class="myClass">I'm alone</span>
</div>

<div>
  <span class="myClass">We are two</span>
  <span class="myClass">We are two</span>
</div>

Answer №2

To avoid code duplication, you can follow Creaforge's suggestion and override the styles only when there is a single .card element. However, this would require specifying the transform and box shadow values twice, which might not be the most efficient approach due to the length of those values.

There are two more concise methods to achieve this:

  1. Utilize a selector. While normally recommending

    .card-stack:hover .card:not(:nth-child(2):last-child)
    , it's worth considering that support for level 4 :not() is still not fully complete. In such cases, you may need to resort to the older method, demonstrated below:

    .card-stack:hover .card:not(:nth-child(2)), .card-stack:hover .card:not(:last-child) {
      transform: translateY(calc((var(--y) * -105% + 200px)));
      box-shadow: none;
    }
    
  2. Remove the .clear element from within the .card-stack element. There doesn't seem to be a substantial reason for its placement there. Subsequently, adjust the selector as follows:

    .card-stack:hover .card:not(:only-child) {
      transform: translateY(calc((var(--y) * -105% + 200px)));
      box-shadow: none;
    }
    

    (Note that in the absence of level 4 :not(), the combination :not(:first-child:last-child) mentioned by Creaforge isn't directly viable in CSS, but you have the option of utilizing :only-child)

Answer №3

To separate them, you can assign the IDs "Card1" and "Card2" to each element and then style them in CSS using #Card1 and #Card2. I hope this solution works for you! :)

Answer №5

Perhaps you could consider dynamically adding a class using JavaScript instead? This involves updating the CSS properties for hover effects and applying the class only if the card-stack element contains more than two children, triggered by the "onmouseover" event.

<div class="card-stack" onmouseover="onHover(this)">
...
</div>
.card-stack-h:hover  .card{
  transform: translateY(calc((var(--y) * -105% + 200px)));
  box-shadow: none;
 }

.card-stack-h:hover .clear {
  visibility: visible;
  transform: translateY(calc((var(--y) * -105% + 200px)));
  position:absolute;
  top:2vh;
  right:40px;
}
function onHover(stack) {
  let cards = stack.querySelectorAll(".card")
  if(cards.length > 1) stack.classList.add("card-stack-h")
  else stack.classList.remove("card-stack-h");
}

Codepen

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 positioning the bootstrap navbar correctly inside a container

I am having some trouble with my HTML page layout. I have a fixed Bootstrap navbar and a container with a width of 1000px. I'm trying to place the navbar inside the container, but it's not working as expected. The navbar is still taking up the fu ...

The include_once function is functioning correctly on one page, but encountering issues on another page. No errors are being displayed

I am currently using Bootstrap for my website. When I include the bottom and footer sections in actualites.php (at the end of the file), everything works smoothly. As I construct my website, I am trying to incorporate content via URL. My code looks like t ...

Distinguishing CSS Variances on ASP.Net Site with Android 4+

I am encountering an issue with my current ASP.Net Mobile Website design. It is rendering correctly on android phones pre 4, iPhones, and Blackberries. This problem requires a bit of setup to explain... CSS tr { color: #00ff00; } #MasterBackButton { ...

Tips for disregarding global CSS in Nuxt.js?

I've been utilizing a boilerplate that integrates with the CoreUI template from GitHub, and it's been working well. However, I am now looking to customize my index page with a unique style, and I'm encountering issues where the global CSS fr ...

Tips and tricks for ensuring images maintain their aspect ratio and height when resizing for responsiveness

I am facing an issue with my two-column layout. One column contains an image and the other column has text and buttons with a fixed height. To ensure the image is responsive, I have set the width to 100% and height to auto. However, upon resizing, the aspe ...

XHTML markup error found: missing end tag for "div" element in W3C validation

Just finished validating my web page using the W3C markup validation service. You can find the results here. Here's what was returned: Error Line 112, Column 7: end tag for "div" omitted, but OMITTAG NO was specified </body> Info Line 16, C ...

Issue with displaying Bootstrap 5 svg icons

I have included a footer using examples from the official Bootstrap documentation, but for some reason, the social icons are not showing up. Here are the CDNs I have added: <link rel="preconnect" href="//fonts.gstatic.com" crossorigi ...

Troubleshooting Full Screen Problems with Three.js

Despite my efforts to troubleshoot, I am still encountering a frustrating issue with the Three.js API. Even after thoroughly studying the API documentation, browsing through StackOverflow questions, and using debugging tools like firebug and chrome's ...

Moving a mouse from one element to another does not reset its state

Link to code: https://codesandbox.io/s/objective-darwin-w0i5pk?file=/src/App.js Description: There are four gray squares in this example, each with a different shade of gray. The goal is to change the background color of each square when the user hovers o ...

Using the <a> tag within a PHP script

Within my PHP code, I utilized the tag. However, when testing the code, the output appeared as a link but was not clickable. $data1 = mysql_query("SELECT * FROM image_upload INNER JOIN user_table ON image_upload.user_id=user_table.user_id WHERE flag=1 ORD ...

Struggling to concentrate on a text field following navigation in an AngularJS application

My current project involves working with an AngularJS application where I am facing a challenge in setting the cursor or focus on a specific text box when routing to a page. Despite my attempts using various methods such as setFocus() in JavaScript, autofo ...

CSS selector for GTM trigger that is not specific to any particular element

I am attempting to develop a CSS selector that can target the specific entries within the page-top-menu: Header menu - Menu 1 DE #page-top-menu > div > div.menu-wrapper > ul > li.i39.dropdown.layer.item-type-1.catid-0eca5a6c6e53f281b9e0469ca3d ...

Having trouble with the ".." shorthand not working in the HTML image directory path

My Website File Structure: -css - home.css -html - index.html -images - banner.png HTML Code: <!DOCTYPE html> <html lang="en"> <head> <title>myWebsite</title> <link rel="stylesheet" typ ...

What's the best way to customize the appearance of an OPTION field using inline text styling

I am attempting to customize the appearance of SELECT / OPTION boxes using INLINE CSS. Unfortunately, my use of background-color is not producing the desired effect: <option style='bakground-color:red'>text</option> My goal is to h ...

Generate a series of buttons with generic identifiers that can be easily targeted using getElementById. The IDs will be dynamically assigned

I am looking to dynamically generate unique IDs for a list of buttons, allowing me to easily target specific buttons using getElementById. Here is an example code snippet where each button has the same ID: @foreach (var cat in Model) { <div clas ...

Creating a form in PHP with the power of JavaScript, AJAX, and jQuery

I have successfully created a registration form using HTML, processed the data with PHP, and utilized javascript, ajax, and jquery. However, I am facing an issue where I want to display a notification stating whether the operation was "inserted/failed" on ...

Utilize Flexbox to arrange elements in a column direction without relying on the position property in CSS

Flexbox - align element to the right using flex-direction: column; without relying on position in CSS Hello everyone, I am looking to move my row element to the right without using positioning. This code includes flex-direction: column; and I do not have ...

Adjusting the alignment of Bootstrap navbar items upon clicking the toggle button

When I click the toggle button on a small screen, my navbar items appear below the search bar instead of aligning with the home and about elements. Below is an image depicting this issue: https://i.stack.imgur.com/4rabW.png Below is the HTML code structu ...

Transitioning from a CSS box-shadow effect to an inset-box shadow on hover

Have you ever encountered the challenge of transitioning from a normal box-shadow to an inset box-shadow? I'm curious if this is the reason why my transition isn't working, or if there's another issue with my code. What steps should I take i ...

What is the best way to ensure an image fills the entire space within a Bootstrap modal container?

I'm having some issues with my bootstrap modals that contain images. When the images are long vertically, a scrollbar appears which is not ideal. I tried to solve this by setting a max-height for the modal-content and making the modal-body (where the ...