Reputation: 4469
How to override the margin-bottom: 20px;
that was set by the framework using it's predefined class .alert
and set it back to 0
when the element is followed by another .alert
element.
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
</head>
<body>
<div class="alert alert-success" role="alert">The <code>margin-bottom: 20px;</code> was set by the framework.</div>
<div class="alert alert-info" role="alert">The <code>margin-bottom: 20px;</code> was set by the framework.</div>
<div class="alert alert-warning" role="alert">The <code>margin-bottom: 20px;</code> was set by the framework.</div>
</body>
I know that an adjacent selector can do a trick by selecting only a followed .alert
element that is immediately preceded by another .alert
element and set it's margin-top
to -20px
but this sounds dirty.
.alert + .alert {
margin-top: -20px;
}
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
</head>
<body>
<div class="alert alert-success" role="alert">The <code>margin-bottom: 20px;</code> was retracted by the followed <code>margin-top: -20px;</code>.</div>
<div class="alert alert-info" role="alert">The <code>margin-bottom: 20px;</code> was retracted by the followed <code>margin-top: -20px;</code>.</div>
<div class="alert alert-warning" role="alert">The <code>margin-bottom: 20px;</code> was not retracted because there's no followed <code>.alert</code> element.</div>
</body>
That CSS will retract the margin-bottom: 20px;
of a preceded .alert
, but is there a way to directly select the .alert
if it comes before another .alert
to override its margin-bottom
to 0
?
Upvotes: 2
Views: 5853
Reputation: 9172
To select elements that preceed others, use :has()
: .alert:has(+ .alert)
. The selector provided to :has
will be used for matching but will not cause the matched element to be selected.
.alert:has(+ .alert) {
margin-bottom: 0;
}
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
</head>
<body>
<div class="alert alert-success" role="alert">The <code>margin-bottom: 20px;</code> was retracted by the followed <code>margin-top: -20px;</code>.</div>
<div class="alert alert-info" role="alert">The <code>margin-bottom: 20px;</code> was retracted by the followed <code>margin-top: -20px;</code>.</div>
<div class="alert alert-warning" role="alert">The <code>margin-bottom: 20px;</code> was not retracted because there's no followed <code>.alert</code> element.</div>
</body>
Upvotes: 2
Reputation: 5724
You're asking for a 'previous sibling' selector by the sounds of it which is not possible.
CSS can only select an element if it is a child or adjacently succeeding it. You cannot select an adjacent preceding element (or parent element) in CSS.
Your solution is perfectly acceptable. Negative margins are sometimes seen as 'dirty' for some reason but this is far from true and is documented officially.
Negative values for margin properties are allowed, but there may be implementation-specific limits.
Your solution is the right one!
Upvotes: 4
Reputation: 288020
If I understand it correctly, you want
.alert {
margin-bottom: 0;
}
.alert:last-child {
margin-bottom: 20px;
}
@import 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css';
.alert {
margin-bottom: 0;
}
.alert:last-child {
margin-bottom: 20px;
}
<div class="alert alert-success" role="alert">The <code>margin-bottom: 20px</code> was overriden by <code>margin-bottom: 0</code>.</div>
<div class="alert alert-info" role="alert">The <code>margin-bottom: 20px</code> was overriden by <code>margin-bottom: 0</code>.</div>
<div class="alert alert-warning" role="alert">The <code>margin-bottom: 20px</code> was overriden by <code>margin-bottom: 20px</code>.</div>
Upvotes: 3