Having trouble getting CSS :last-of-type to work properly alongside :not?

I have encountered an issue with selecting the last list item in a specific case. I have a list of items where only one can be selected at a time, and when selected, it should be displayed at the top of the list using flex ordering. However, I am having trouble ensuring that the last selected item does not have a border. I have tried using various selectors, including

.selection li:not(.selected):last-of-type
, but the last-of-type selector is not behaving as expected. The problem arises when the last list item is the one selected, resulting in a double border at the bottom of the list instead of a single border coming from the unordered list element.

In my CSS code snippet, you can see the styles I applied and the selector causing the issue. I have also provided a Codepen snippet to demonstrate the problem.

Any insights or suggestions on how to resolve this issue would be greatly appreciated. Thank you for your help!

Answer №1

Consider taking a different approach with the following suggestions:

  • Eliminate the use of the :not selector completely
  • Add borders to the left, right, and top of the ul element only
  • Apply the bottom border specifically to the li elements

ul {
    display: flex;
    flex-direction: column;
    border-top: .15rem solid #666;
    border-left: .15rem solid #666;
    border-right: .15rem solid #666;
}

li { border-bottom: .15rem solid #666; }

Revised Codepen Link


Explanation on why your current selector is not functioning as expected:

.selection li:not(.selected):last-of-type { border-bottom: none; }

It seems like you are trying to target the last li element unless it has the class selected.

However, the last-of-type selector does not work based on classes but rather on DOM elements. This means that even if an li is hidden with display: none, it will still be selected by the specified selector.

6.6.5.9. :last-of-type pseudo-class

The :last-of-type pseudo-class represents the last sibling of its type among its parent's children elements.

source: https://drafts.csswg.org/selectors-3/#last-of-type-pseudo

For more information, check out: How to make nth-child selector skip hidden divs

Answer №2

Instead of attempting to eliminate the border-bottom from the last unselected item (which can be difficult or even impossible in CSS), a simpler approach is to apply a border-top to each item and then remove the excess border from the visually superior item, which happens to be... .selected!
Your requirement for:

having a distinct border on my list elements than the overall outer border

is achievable with this solution.

View updated pen

.selection ul {
  display: flex;
  flex-direction: column;
  border: .15rem solid #666;
}

.selection li {
  order: 2;
  border-top: .15rem dashed #666;
  background: lightblue;
}

.selection li.selected {
  order: 1;
  border-top: none;
  background: tomato;
}

/** Additional styles for context **/
ul { list-style: none; padding: 0; width: 25%; margin: 2rem auto; }
li { padding: 1rem 2rem; background-color: #ebebeb; }
li:hover { background-color: #ccc; }
a { color: inherit; text-decoration: none; }
<div class="selection">
  <ul>
    <li><a href="">1</a></li>
    <li><a href="">2</a></li>
    <li class="selected">3</li>
  </ul>
</div>

Answer №3

Think of this more like a clever workaround rather than a straightforward solution.

This demo serves to prove that with some CSS manipulation, it is indeed possible.

The highlighted element in yellow indicates the selection.

.selection ul {
  display: flex;
  flex-direction: column;
  border: .15rem solid #666;
}

.selection li {
  order: 2;
  border-bottom: .15rem dashed #666;
}

div.selection li.selected {
  order: 1;
  background-color: yellow;
}

.selection li:nth-last-child(2) {
  order: 3;
}

.selection li:not(.selected):nth-last-child(2) {
  border-bottom: none;
}

.selection li.selected:nth-last-child(2) ~ li {
  border-bottom: none;
}


/** Non-essential styles for context **/
ul { list-style: none; padding: 0; width: 25%; margin: 2rem auto; }
li { padding: 1rem 2rem; background-color: #ebebeb; }
li:hover { background-color: #ccc; }
a { color: inherit; text-decoration: none; }
.selection {display: inline-block; width: 160px;}
<div class="selection">
  <ul>
    <li><a href="">1</a></li>
    <li><a href="">3</a></li>
    <li class="selected">2</li>
  </ul>
</div>
<div class="selection">
  <ul>
    <li><a href="">1</a></li>
    <li><a href="">3</a></li>
    <li><a href="">2</a></li>
  </ul>
</div>
<div class="selection">
  <ul>
    <li><a href="">1</a></li>
    <li class="selected"><a href="">3</a></li>
    <li><a href="">2</a></li>
  </ul>
</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

Adjusting the width of a nested iframe within two div containers

I am trying to dynamically change the width of a structure using JavaScript. Here is the current setup: <div id="HTMLGroupBox742928" class="HTMLGroupBox" style="width:1366px"> <div style="width:800px;"> <iframe id="notReliable_C ...

What is the proper way to eliminate the top margin from a div that has the display table-cell property?

There are two div elements with display: table-cell property: <div> This is a table cell </div> <div> <h1>Some content</h1> <h1>Some content</h1> <h1>Some content</h1> <h1>Som ...

"When setting up a window.EventListener, the Div element fails to be hidden when setting its display property to 'none

I'm working on creating a preloader by displaying an overlay until all the content on the page is loaded. However, despite checking my code multiple times, I can't seem to figure out why it's not working. If anyone could provide some assist ...

Use jQuery ajax to send form data and display the received information in a separate div

I'm working on a PHP test page where I need to submit a form with radios and checkboxes to process.php. The result should be displayed in #content_result on the same page without refreshing it. I attempted to use jQuery Ajax for this purpose, but noth ...

Updating the style sheet of a selected menu item on an ASP.NET master page

I created an asp.net master page with a menu setup like this: <menu id="menu"> <nav id="main_nav"> <ul id="menu-primary"> <li ><a href="./">Home</a></li> <li><a href="staff.aspx"& ...

When the columns start stacking in Bootstrap, the padding is disabled

As I work on revamping my website, I have decided to incorporate the Bootstrap framework. While I can navigate through HTML coding, I still consider myself a novice when it comes to coding. The current issue I am facing involves the alignment of two colum ...

What is the best way to showcase entire content over a background image on a mobile device?

Hello, I am facing an issue with displaying content on an image in desktop view that does not resize properly when the browser window is resized. The problem lies in setting a background image with full content. Can you please take a look at my images belo ...

Organizing my website directories using external tools

I am dealing with a website that follows this specific structure: \ |--css | \ | |--vendors | | \ | | |--normalize.css | | |--... | | | |--styles.css | |--media-queries.css | |--js | \ | |--vendors | | \ | | |- ...

How can I bypass hotlink protection for RSS images?

According to the definition, RSS feeds are considered public. When images are displayed within the feed, it is essentially "hotlinking," meaning that the content is being read directly from the Internet rather than your local machine. Is there a specific ...

What is the best way to layer a background image with a CSS gradient?

I've spent over an hour searching for the right answer with no luck, so I'm turning to you for help. On my main page, there's a div with a large image that looks like this: <div id="hero"></div> It's working perfectly at t ...

iOS 8: mysterious void found at the bottom of the Safari home screen page in full screen mode

Hello everyone, I hope you can assist me with a dilemma I am facing. Despite being a long-time reader of this forum, this is my first time posting here. I have searched extensively online for solutions to my issue but have not found anything recent or effe ...

What is the best way to ensure that pagination remains in a static position?

My task tracker allows me to show 4 tasks per page, with additional tasks moving to the next page using React pagination when there are more than 4. I need the page numbers to remain fixed in position and not move. For example, if I have 2 pages of tasks ...

Inject AngularJS variable bindings into the view alongside HTML code

Is it possible to insert HTML markup into an Angular variable? app.js function myController($scope){ $scope.myItem = '<p>' + Example + '</p>'; } index.html <div ng-controller="myController">{{myItem}}</div&g ...

Concealing HTML content with a modal overlay

There are security concerns with my authentication overlay modal, especially for users familiar with CSS and HTML. Is there a way to hide the HTML behind the modal so it doesn't appear in the page source? The code below is just an example of a modal ...

With the addition of a key element in the opening statement

Take a look at this code snippet: <div class="content"> This is some title<br/> Some text<br/> And maybe more text. </div> I am trying to wrap the first sentence with a <span> tag before the <br/> element, like s ...

Error in WebGL rendering: attribs are not configured properly

Below is the code for my vertex shader: attribute vec3 aVertexPosition; attribute vec4 aVertexColor; attribute float type; uniform mat4 uMVMatrix; uniform mat4 uPMatrix; varying vec4 vColor; void main(void) { gl_Positi ...

What is the best way to attach a button to a mat-drawer?

I am facing an issue with aligning a button to a mat drawer located to the right of the screen to ensure a clear overall design. Check out this example How can I achieve this alignment? My current approach involves placing the button inside the drawer an ...

Bootstrap's (g-) gap feature seems to be malfunctioning, unfortunately

Even though I followed the grid structure from Bootstrap reference, my code doesn't seem to have horizontal gaps, only vertical ones. I know it's not about the version because when I copy and paste the sample code into my HTML file, that code sti ...

Show the meta-field mp3 and place it in a lightbox container on the portfolio page

My Current Portfolio Gallery Setup: Currently, my portfolio gallery is displayed in a masonry grid format using the JIG plugin. This grid showcases images from my custom post_type. When clicking on a thumbnail, a lightbox pops up showing the full photo. T ...

What are the style attributes that can be edited in each ant design component?

My goal is to customize an ant design card by adding a border only on the left and right sides of the card. The bordered attribute in the card component seems to either remove the entire border or display it on all sides. I am looking for a way to specif ...