:last-child pseudo-class mixed with attribute selector not working
I'm trying to select the first and last child of an element with a specific
data-
attribute.
Bottom line is, there's no way to do that in CSS.
last-child
(and last-of-type
) mean, well, "last child", and "last child of type", they do not mean "last child matching the entire selector including an attribute selector". In your case, it is likely that the third div
is not actually the last child (or not the last div
) within the parent element; it's impossible to tell unless you show the entire HTML including the parent element and all its children.
:last-child not working as expected?
The last-child
selector is used to select the last child element of a parent. It cannot be used to select the last child element with a specific class under a given parent element.
The other part of the compound selector (which is attached before the :last-child
) specifies extra conditions which the last child element must satisfy in-order for it to be selected. In the below snippet, you would see how the selected elements differ depending on the rest of the compound selector.
.parent :last-child{ /* this will select all elements which are last child of .parent */ font-weight: bold;}
.parent div:last-child{ /* this will select the last child of .parent only if it is a div*/ background: crimson;}
.parent div.child-2:last-child{ /* this will select the last child of .parent only if it is a div and has the class child-2*/ color: beige;}
<div class='parent'> <div class='child'>Child</div> <div class='child'>Child</div> <div class='child'>Child</div> <div>Child w/o class</div></div><div class='parent'> <div class='child'>Child</div> <div class='child'>Child</div> <div class='child'>Child</div> <div class='child-2'>Child w/o class</div></div><div class='parent'> <div class='child'>Child</div> <div class='child'>Child</div> <div class='child'>Child</div> <p>Child w/o class</p></div>
last-of-type selector not working as expected
Instead of <div>
s and <label>
s use <fieldset>
s and <legend>
s because:
- It makes your
<form>
semantically perfect. - It looks better
- Using CSS as the main means of finding elements in the DOM is very limiting, so having
<div>
s and<span>
s everywhere will lessen your chances at getting specific selectors.
Now your layout is semantic, and using nth-of-type
is a no brainer:
Demo
fieldset:last-of-type {
margin-bottom: 50px;
border-color: red
}
<form role="form" method="POST" action="{{ route('login') }}">
{{ csrf_field() }}
<fieldset class="form-input">
<legend>Username</legend>
<input id="email" placeholder="Enter your email" type="email" name="email" value="{{ old('email') }}" required autofocus>
</fieldset>
<fieldset class="form-input">
<legend>Password</legend>
<input id="password" placeholder="Enter your password" type="password" name="password" required>
</fieldset>
<fieldset class="form-input">
<legend>Username</legend>
<input id="email" placeholder="Enter your email" type="email" name="email" value="{{ old('email') }}" required autofocus>
</fieldset>
<fieldset class="form-input">
<legend>Password</legend>
<input id="password" placeholder="Enter your password" type="password" name="password" required>
</fieldset>
<fieldset class="form-input">
<legend>Username</legend>
<input id="email" placeholder="Enter your email" type="email" name="email" value="{{ old('email') }}" required autofocus>
</fieldset>
<fieldset class="form-input">
<legend>Password</legend>
<input id="password" placeholder="Enter your password" type="password" name="password" required>
</fieldset>
<fieldset class="form-input">
<legend>Username</legend>
<input id="email" placeholder="Enter your email" type="email" name="email" value="{{ old('email') }}" required autofocus>
</fieldset>
<fieldset class="form-input">
<legend>Password</legend>
<input id="password" placeholder="Enter your password" type="password" name="password" required>
</fieldset>
<fieldset class="form-input">
<legend>Username</legend>
<input id="email" placeholder="Enter your email" type="email" name="email" value="{{ old('email') }}" required autofocus>
</fieldset>
<fieldset class="form-input">
<legend>Password</legend>
<input id="password" placeholder="Enter your password" type="password" name="password" required>
</fieldset>
<fieldset class="form-input">
<legend>Username</legend>
<input id="email" placeholder="Enter your email" type="email" name="email" value="{{ old('email') }}" required autofocus>
</fieldset>
<fieldset class="form-input">
<legend>Password</legend>
<input id="password" placeholder="Enter your password" type="password" name="password" required>
</fieldset>
<div class="buttonWrapper">
<button type="submit">Login</button>
</div>
<div style="padding-bottom: 20px;" class="text-center">
<a class="text-uppercase text-condensed" href="">
Forgot Your Password?
</a>
</div>
</form>
Combining :last-child with :not(.class) selector in CSS
Not with CSS selectors alone, no, as :last-child
specifically looks at the last child, and there isn't a similar :last-of-class
pseudo-class. See my answer to this related question.
As of late 2015, implementations have begun slowly trickling in for Selectors 4's extension to :nth-child()
and :nth-last-child()
which allow you to pass an arbitrary selector as an argument (more on that also in an update to the linked answer). You will then be able to write the following:
tr:nth-last-child(1 of :not(.table_vert_controls))
Although implementations have recently begun to ship, it will still take at least a few more years for this to be widely supported (as of April 2018, two and a half years after being the first browser to ship, Safari remains the only browser to have done so). In the meantime, you'll have to use something else, like an extra class just before the class in question, or a jQuery selector:
$('tr:not(.table_vert_controls):last')
Pseudo selector :last-child not working
All your nav-link
are the last child to the parent element. Try this instead. Also not that it doesn't have to be this specific but I assume you know about specificity so I'll keep it as is.
.navbar {
.navbar-nav {
.nav-link {
border-right:1px solid red;
}
li {
&:last-of-type {
.nav-link {
border-right:none;
}
}
}
}
}
Note that you have a stray closing li
element.
CSS selector to check that attribute does not contain both values
As you mentioned, you want something equivalent to :not([style*='display'][style*='none'])
, which is invalid in CSS, since :not()
allows no combined selectors.
The laws of logic help us out here. Remember that !(a AND b) == !a OR !b
, so we can write
:not([style*='display']), :not([style*='none'])
since in CSS, a, b
matches elements that satisfy selector a
OR selector b
.
Again, as said in the question, this does not take the order of the words into consideration. The latter is impossible in CSS, since none of the CSS attribute selectors consider word order.
Last child not working as expected with p tag
p.info:last-child
matches all p.info
elements that are also the last children of their parent.
In your markup, p.header
are not the last children of their parent so while p.header
matches various elements, p.header:last-child
will match none.
Unfortunately, there is no :last-of-its-class
selector. Matching is not possible unless you make some assumptions about the HTML structure. I made one:
p.header:nth-last-child(2) { }
It matches all p.header
elements that are second last children of their parent. Note that this requires CSS3 selectors support.
p { background: #CCC; }p.info:last-child { background: #FC0; }p.header:nth-last-child(2) { background: #FC6; }
<div class="port-container"> <div class="header"><h1>Portfolio</h1></div> <p class="header" ref="who">Who am I?</p> <p class="info" ref="who">...</p> <p class="header" ref="what">What do I do?</p> <p class="info" ref="what">...</p> <p class="header" ref="projects">Current Projects?</p> <p class="info" ref="projects">...</p> <p class="header" ref="conntact">Contact me</p> <p class="info" ref="conntact">...</p></div>
:last-of-type doesn't work
:last-of-type
matches an element which is the last element of its type (tag) within its (first-level) parent, period. It doesn't know or care about what other selectors you may have combined, including class selectors such as .item-input
, or anything else.
There is no straightforward way in CSS to accomplish what you want, which could be expressed as :last-of-selector
. Some alternatives that have been suggested include
Wrap the first four elements in a separate div, so you can do
:last-of-type
within it.Have somebody (server, local JS) mark the element you want with a specific class, and refer to it.
Other hacks, such as hard-wiring the number of extra elements at the end that you want to skip, and use
:nth-last-of-type
.Give the elements in question a different tag, if you can so manage, and then you can use
last-of-type
.
Related Topics
CSS Values Using HTML5 Data Attribute
Apply CSS Style to Child Elements
How to Keep CSS Floats in One Line
How to Center a Bootstrap Div with a 'Spanx' Class
How to Add a Margin to a Table Row <Tr>
How to Have a Position: Fixed; Behaviour for a Flexbox Sized Element
Shrinking Navigation Bar When Scrolling Down (Bootstrap3)
How Does Object-Fit Work with Canvas Element
Two Divs, One Fixed Width, the Other, the Rest
How to Customize the HTML5 Input Range Type Looks Using CSS
Less and Bootstrap: How to Use a Span3 (Or Spanx [Any Number]) Class as a Mixin
How to Efficiently Load Google Fonts in Nuxt
Perspective and Translatez Moves Diagonally
CSS - First Child Without Certain Class
CSS Specificity or Inheritance
How to Fix Unexpected Column Order in Bootstrap 4
Is There a Reason Why CSS Doesn't Support Ids and Classes, Starting from Numbers