Apply specific margins to first and last element that are not siblings - html

I have specific type of boxes in my HTML that have, let's say margin: 10px; to all of them. They are displayed in a row on the page (using Bootstrap) and I want to remove the left margin of the first element and the right margin of the last element. I could use :first-child or :first-of-type and their respective lasts but the elements are not siblings and they do not have a common parent. The HTML looks something like this:
<div class='container'>
<div class='col-md-2'>
<div class='MY-CUSTOM-BOX'>
</div>
</div>
<div class='col-md-5'>
<div class='MY-CUSTOM-BOX'>
</div>
</div>
<div class='col-md-5'>
<div class='MY-CUSTOM-BOX'>
</div>
</div>
</div>
:first-of-type applies to all boxes, not sure how to approach the :first-child because of the nested divs. Any ideas?

It looks like you could use a combination of css selectors to achieve this, namely the > as well as :first-child and :last-child
:first-child > .MY-CUSTOM-BOX {
margin-left: 0;
}
:last-child > .MY-CUSTOM-BOX {
margin-right: 0;
}
This selects the direct MY-CUSTOM-BOX descendants of any first and last child elements.
That should work where the boxes have the same level of parent (i.e. container -> div -> MY-CUSTOM-BOX)
You could also do it the other way round which may give you better results depending on how nested you are:
.container > :first-child .MY-CUSTOM-BOX {
margin-left: 0;
}
.container > :last-child .MY-CUSTOM-BOX {
margin-right: 0;
}
This selects the first and last child of container and then gives any MY-CUSTOM-BOX elements inside it margin left/right of 0.
Here's a (relatively crude) fiddle demonstrating both examples: https://jsfiddle.net/ttakchr1/

Related

Why isn't :last-of-type working on tumblr? [duplicate]

This question already has answers here:
Can I combine :nth-child() or :nth-of-type() with an arbitrary selector?
(8 answers)
Closed 5 years ago.
Despite limiting the :last-of-type to a certain div, when I add another div under that div, the :last-of-type class is suddenly canceled. Is there a reason why?
.container {
width: 400px;
border-bottom: 1px solid #111;
}
.container:last-of-type {
border-bottom: 0;
}
<div class="entry">
<div class="container">
{block:Posts} ....... {/block:Posts}
</div>
<div class="pagination">....</div>
</div>
Using this code, if I removed the .pagination div, the :last-of-type works normally and removes the border-bottom.But if I add the .pagination div, suddenly the :last-of-type doesn't work even though the .pagination div isn't included in the container class.
Is there a way to fix it? Or to select the last div of the .container div without having the .pagination class affecting it?
You’re selecting .container, not the last of its children. The form .container:last-of-type selects anything of class .container that is the last of its type. By inserting a space, which is the generic descendant selector, or a right angle bracket (>), which is the direct descendant selector, you’re now selecting the last of a given type within any element of class .container.
.container > :last-of-type
This may not be your best option, though. You should consider whether last-child makes more sense. For example, if you introduce elements of different a types at some point, the last of each type will be selected.
last-of-type refers to the element type (in this case div), not to the class, so it won't work the way you expect it, but will select the .pagination DIV, which is the last DIV inside the container element.
However, if the last .container div is always the second last DIV in there (only followed by the .pagination div, you can use :nth-last-of-type(2):
.container {
width: 400px;
border-bottom: 1px solid #111;
}
.container:nth-last-of-type(2) {
border-bottom: 0;
}
<div class="entry">
<div class="container">
container content
</div>
<div class="container">
container content
</div>
<div class="container">
container content
</div>
<div class="container">
container content
</div>
<div class="pagination">....</div>
</div>

Differentiate element from inline text

I'd like have a margin on an element, on the right if the element is the first element of the parent <div>, or on the left if the element is the last element of the parent <div>.
The thing is, there is no other element in the <div>, only plain text.
Here's where I am:
HTML:
<div class="parent">
<i>→</i>Action
</div>
<div class="parent">
Action<i>←</i>
</div>
CSS:
.parent i:first-child {
margin-right: 5px;
}
.parent i:last-child {
margin-left: 5px;
}
With the first selector I'm trying to target the first <div>, and with the last selector I'm trying to target the last <div>.
But actually since <i> is the only child element, both rules apply to this element.
See fiddle.
Is there a way I can select the <i> that is at the beginning or the end of the parent, without modifying the markup? (Adding a <span> to wrap the text is not the solution I'm looking for...)
Based on this question, and on the comments on my original question here, it seems that there is no way to achieve text node selection in CSS.
Therefore to address my issue I have to wrap my text node in an inline element, like <span>, in order for my :first-child and :last-child selectors to work as expected.
See updated fiddle
<div class="parent">
<i>→</i>Action
</div>
<div class="parent">
Action<i>←</i>
</div>
<div class="clearfix"></div>
.parent {
float: left;
}
.parent:first-child {
margin-right: 5px;
}

Is it possible in CSS to select an element specifically without an ID or class?

I am making a theme for a website, but I ran into a problem. I can't change their HTML or use javascript, only CSS.
This is what the site's HTML looks like:
<div class="container">
<div style="margin:a ridiculously massive number">
<p id="title"> Title of page </p>
<p> Words that cannot be read because of the ridiculous margin </p>
</div>
<div id="otherContent"> There a lot of divs without ridiculous margin all with different ids </div>
</div>
I want to remove the ridculous margin without affecting the other divs margins. Is this possible?
yes you can target the div that is the first-child inside of .container as to not effect other divs.
.container div:first-child{
//code
}
EXAMPLE 1
Example 1 is specifically for the example you posted where the div you would like to target is the first child of it's parent. Also note if the margin is inline like your example you're going to have to over-ride it with !important like so:
.container div:first-child{
margin: 0 !important;
}
OR
You could also use the :not selector if the other's have a similar class
.container div:not(.classname) {
//code
}
EXAMPLE 2
The point of example 2 is if your div isn't the first child and the only without a class (it would probably be unlikely you would have multiple divs with the same classname except one but it's possible). in your example you could also use :not() to target that other div with id #otherContent like so:
.container div:not(#otherContent) {
//code
}
OR
The last option you can use if the others don't apply would be nth-of-type() to target specifically which one you want to effect:
.container div:nth-of-type(2) {
//code
}
EXAMPLE 3
In this case you will have to use first-child selector with !important keyword, as this is the only way to make rule more specific than style="margin" rule:
.container > div:first-child {
margin: 0 !important;
}
If all the other divs have ID you can use the following:
div>div:not([id]) {
margin: 0 !important;
}

how to select a class wrapped in a specific container

I'd like to add a margin-top:5px to a subset of classes in the following:
This part is wrong:
.af-mh-container-1011.af-row{
margin-top: 5px;
}
with this html:
<div class='af-mh-container-1011'>
<!-- add to this one -->
<div class='af-row'>
here i am
</div>
</div>
<div class='af-mh-container-not-1011'>
<div class='af-row'>
here i am
</div>
</div>
.af-mh-container-1011.af-row selector tries to match an element having both af-mh-container-1011 and af-row classes.
In order to select the nested child <div> having af-row class, you could use direct descendant combinator A > B as follows:
.af-mh-container-1011 > af-row {
margin-top: 5px;
}
Also A B would match the nested B which is a descendant of A element - and not necessarily a direct descendant or a child.
Probably you missed a space between the dot -
.af-mh-container-1011 .af-row{
margin-top: 5px;
}
JSFIDDLE - http://jsfiddle.net/zgf0v0tn/
What you have written is applying a margin to an element with both those classes.
You want to target child elements.
Here are a few options:
.af-mh-container-1011 > .af-row {
margin-top: 5px;
}
.af-mh-container-1011 .af-row {
margin-top: 5px;
}
.af-mh-container-1011 div {
margin-top: 5px;
}
All three options will affect your af-row class. The first option is a child selector. This will only affect the direct child. Other divs nested within the .af-row won't be affected. The second option will affect your af-row and any element nested within .af-row with the same class. The last option will affect all divs within af-mh-container-1011. See the example below for further clarification.
<div class='af-mh-container-1011'>
<div class='af-row'>
<div class='af-row'>
This nested element is unaffected by a child selector (first option) but is affected by a decendant selector (second option). It is also affected by the 3rd option.
</div>
</div>
</div>

How do you make nth-child work with descendant selectors?

I have this code.
<div class="myDiv">
<div>
I want to be red.
</div>
</div>
<p>I'm some other content on the page</p>
<div class="myDiv">
<div>
I want to be blue.
</div>
</div>
.myDiv div:nth-child(odd) {
color: red;
}
.myDiv div:nth-child(even) {
color: blue;
}
I see why it's not working. It's making every odd div within myDiv be red. What I want it to do is make every odd example of a div within myDiv be red. How can I write that?
Here's a JSFiddle.
There are a couple of problems here. The :nth-child is on the wrong element. The inner divs are always the first child, so the :nth-child(odd) selector works for both. Instead move to
.myDiv:nth-child(odd) div
...however this does not work either because of the <p>. A working solution with your sample is
.myDiv:nth-of-type(odd) div
http://jsfiddle.net/tvKRL/1/
NOTE that the nth-of-type only works because the .myDiv elements are all divs (it's based on the element, not the selector), so the selector ignores the <p>. If there can be another div between .myDivs I don't think any CSS will work for what you want to do.
You can't do this generically, for the reason given by Domenic. To put it simply: there's no selector that lets you filter an existing subset of matched elements.
On the off chance that among your p and div.myDiv siblings the only div elements are the ones with that class anyway, then you could use :nth-of-type() to have it look at those intermediate divs only:
div.myDiv:nth-of-type(odd) div {
color: red;
}
div.myDiv:nth-of-type(even) div {
color: blue;
}
Or if there are other divs without that class which should be excluded, then unless there is some sort of pattern in which they're laid out, you're out of luck.
This is not possible. There is no CSS selector that will do what you want, as you can see by perusing the complete list of selectors.
In general CSS selectors do not "reach out" to encompass elements above the DOM tree of the one selected. You are asking for something even more sophisticated than that, combining characteristics of parent elements with ordinal properties of the targeted elements, even though those targeted elements are distributed among entirely different places in the DOM tree.
Just applynth-childto the first member of the descendant selector, not the last one.
div:nth-of-type(odd) > div {
color: red;
}
div:nth-of-type(even) > div {
color: blue;
}
<div class="myDiv">
<div>
I want to be red.
</div>
</div>
<p>I'm some other content on the page</p>
<div class="myDiv">
<div>
I want to be blue.
</div>
</div>