Insert a number before each div with a specific class - javascript

The problem:
I've got a few divs with the same class. I want to place a number (start from 2 to --) before each div.
This is what I tried:
let optionNumber = $(".product-configure-custom-option")
$('.product-configure-custom').each(function () {
if ( $(this).find("div.product-configure-custom-option").length ) {
$('<div class="title-number float-left text-center mr-2">' + $(optionNumber).length + '</div>').insertBefore(optionNumber)
}
});
.product-configure-custom-option{
float:right;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<div class="product-configure-custom">
<div class="product-configure-custom-option">Option 2</div>
<div class="product-configure-custom-option">Option 3</div>
<div class="product-configure-custom-option">Option 4</div>
<div class="product-configure-custom-option">Option 5</div>
<div class="product-configure-custom-option">Option 6</div>
<div class="product-configure-custom-option">Option 7</div>
</div>
</div>
What I want the result to be:
Option Two
Option Three
Option Four

let optionsContainer = $(".product-configure-custom");
optionsContainer.each(function() {
let options = $(this).find("div.product-configure-custom-option");
if (options.length) {
options.each(function(index, option) {
let startValue = 2;
let incrementedValue = startValue + index;
$('<div class="title-number float-left text-center mr-2">' + incrementedValue + '</div>').insertBefore(option);
});
}
});
.product-configure-custom-option{
float:right;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<div class="product-configure-custom">
<div class="product-configure-custom-option">Option 2</div>
<div class="product-configure-custom-option">Option 3</div>
<div class="product-configure-custom-option">Option 4</div>
<div class="product-configure-custom-option">Option 5</div>
<div class="product-configure-custom-option">Option 6</div>
<div class="product-configure-custom-option">Option 7</div>
</div>
</div>

I think you want something like this:
var start = 2;
$(document).ready(function() {
$('.product-configure-custom-option').each(function() {
console.log(this.innerHTML);
this.innerHTML = start + '. ' + this.innerHTML;
start++;
});
});
Although the CSS needs looking at after that.
Looks something like this: https://jsfiddle.net/qzhtr80d/2/

At the moment you're generating a single extra <div> for every <div> found. A more elegant way would be getting the text content of every <div> directly and prepend the counter there.
$(this).find("div.product-configure-custom-option")
returns an object we can use to iterate over the individual elements using a for-loop and do the changes via plain JavaScript. The child element can be queried by the .firstChild property and the actual text is accessible using .data.
Here's an example:
$('.product-configure-custom').each(function() {
let elements = $(this).find("div.product-configure-custom-option");
for (var a = 0; a < elements.length; a++) {
elements[a].firstChild.data = (a + 2) + ". " + elements[a].firstChild.data;
}
});
.product-configure-custom-option {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<div class="product-configure-custom">
<div class="product-configure-custom-option">Option 2</div>
<div class="product-configure-custom-option">Option 3</div>
<div class="product-configure-custom-option">Option 4</div>
<div class="product-configure-custom-option">Option 5</div>
<div class="product-configure-custom-option">Option 6</div>
<div class="product-configure-custom-option">Option 7</div>
</div>
</div>

Not the answer you're asking for, but you can do this in plain CSS: MDN Using CSS counters
.product-configure-custom {
counter-set: foo 1;
}
.product-configure-custom-option::before {
counter-increment: foo;
content: counter(foo) ". ";
}
<div class="wrapper">
<div class="product-configure-custom">
<div class="product-configure-custom-option">Option 2</div>
<div class="product-configure-custom-option">Option 3</div>
<div class="product-configure-custom-option">Option 4</div>
<div class="product-configure-custom-option">Option 5</div>
<div class="product-configure-custom-option">Option 6</div>
<div class="product-configure-custom-option">Option 7</div>
</div>
</div>

Related

How to target a part of CSS class name?

Example 1 works:
HTML:
<div class="items">
<div class="item">item 1</div>
<div class="prefix-item-suffix">item 2</div>
<div class="item">item 3</div>
</div>
CSS:
div[class^="prefix"][class$="suffix"] {
color: red;
}
Example 2 doesn't:
HTML:
<div class="items">
<div class="item">item 1</div>
<div class="multiple prefix-item-suffix classes">item 2</div>
<div class="item">item 3</div>
</div>
CSS:
div[class^="prefix"][class$="suffix"] {
color: red;
}
Example 2 has multiple classes so CSS approach stops working. In real time project the multiple classes will be random except the one targeted in between them, the value between prefix-the_dynamic_value-suffix will also be random, how to target that with other classes inside same element? Because example 1 approach doesn't work.
Try [class*=…]
div[class*="prefix-"][class*="-suffix"] {
color: red;
}
<div class="items">
<div class="item">item 1</div>
<div class="multiple prefix-item-suffix classes">item 2</div>
<div class="item">item 3</div>
</div>
You could do this with js by checking if some class on the element starts with prefix and ends with suffix. If the check returns true then you run your code.
document.querySelectorAll('.items > div').forEach(el => {
const check = [...el.classList].some(cls => {
return cls.startsWith('prefix') && cls.endsWith('suffix')
})
if (check) {
el.style.color = 'red'
}
})
<div class="items">
<div class="item">item 1</div>
<div class="multiple prefix-item-suffix classes">item 2</div>
<div class="item prefix-item-suffix-not-this">item 3</div>
</div>

open and close menus

I have 4 menus and with this piece of code, i can show menus and hide them with specific btns .my question is how can i when i open a menu and i don't close it and then I open another one close previous menus? i tried to store the open menu in a variable and check it when i open another one but it didn't work.
<body>
<div class="container"> ‌
<div class="menu">
<button class="btn">open</button>
<div class="items">
<div class="items-container">
<div class="item">item 1</div>
<div class="item">item 2</div>
<div class="item">item 3</div>
<div class="item">item 4</div>
<div class="item">item 6</div>
</div>
</div>
</div>
<div class="container"> ‌
<div class="menu">
<button class="btn">open</button>
<div class="items">
<div class="items-container">
<div class="item">item 1</div>
<div class="item">item 2</div>
<div class="item">item 3</div>
<div class="item">item 4</div>
<div class="item">item 6</div>
</div>
</div>
</div>
<div class="container"> ‌
<div class="menu">
<button class="btn">open</button>
<div class="items">
<div class="items-container">
<div class="item">item 1</div>
<div class="item">item 2</div>
<div class="item">item 3</div>
<div class="item">item 4</div>
<div class="item">item 6</div>
</div>
</div>
</div>
<div class="container"> ‌
<div class="menu">
<button class="btn">open</button>
<div class="items">
<div class="items-container">
<div class="item">item 1</div>
<div class="item">item 2</div>
<div class="item">item 3</div>
<div class="item">item 4</div>
<div class="item">item 6</div>
</div>
</div>
</div>
</div>
</body>
const btns = document.querySelectorAll(".btn");
btns.forEach(btn => {
const menu = btn.parentElement;
const items = menu.querySelector(".items");
const itemsContainer = items.querySelector(".items-container");
const itemsContainerHeight = itemsContainer.getBoundingClientRect().height;
let previousActivebtn = "";
btn.addEventListener("click", (e) => {
// change btn text
if (e.currentTarget.innerHTML == "open") {
e.currentTarget.innerHTML = "close";
} else {
e.currentTarget.innerHTML = "open";
}
//show and hid the menus
if (!items.classList.contains("item-active")) {
items.classList.add("item-active");
items.style.height = itemsContainerHeight + 32 + "px";
} else {
items.classList.remove("item-active");
items.removeAttribute("style");
}
});
});
You overcomplicate it. You could create a CSS rule which would ensure that .items is hidden, unless .menu is opened:
.menu .items:not(.open) {
display: none
}
And you could create a function like this:
function open(item) {
if (!item.classList.contains("open")) {
//Hide whatever was opened
for (let it of document.querySelectorAll(.menu .items.open)) {
it.classList.remove("open")
}
item.classList.add("open");
} else {
item.classList.remove("open");
}
}
Just pass to this function the item having the class of items.

How can I target a box in order to hide it with jQuery?

I'm trying to make a function in order to hide the boxes with their corresponded number, but I have no idea on how to do it. I tried to figure out how to do it, but every method I come up with ends up on an error.
I'm using jQuery library and Bootstrap.
CSS :
.random {
width: 100 px;
height: 100 px;
background - color: lightgreen;
margin: 30 px;
}
HTML :
<div class="container">
<div class="row">
<div class="col">
<div class="container text-center">
<div id="box_1" class="random">Box 1</div>
<div id="box_2" class="random">Box 2</div>
<div id="box_3" class="random">Box 3</div>
<div id="box_4" class="random">Box 4</div>
<div id="box_5" class="random">Box 5</div>
<div id="box_6" class="random">Box 6</div>
<div id="box_7" class="random">Box 7</div>
<div id="box_8" class="random">Box 8</div>
<div id="box_9" class="random">Box 9</div>
<div id="box_10" class="random">Box 10</div>
</div>
</div>
<div class="col">
<button onclick="NumberFunction(Math.floor(Math.random() * 10) + 1)" class="mt-5 btn btn-outline-danger">Reveal a random box</button>
</div>
</div>
</div>
JavaScript :
$(document).ready(function() {
$(".task_hidden").hide();
var box_1 = $('#box_1');
var box_2 = $('#box_2');
var box_3 = $('#box_3');
var box_4 = $('#box_4');
var box_5 = $('#box_5');
var box_6 = $('#box_6');
var box_7 = $('#box_7');
var box_8 = $('#box_8');
var box_9 = $('#box_9');
var box_10 = $('#box_10');
});
function NumberFunction(random) {
console.log(random);
if (random = 1) { box_1.hide(); }
if (random = 2) { box_2.hide(); }
if (random = 3) { box_3.hide(); }
if (random = 4) { box_4.hide(); }
if (random = 5) { box_5.hide(); }
}
Your code was not working fine because you had declared variables box_1, box_2 inside the ready function which were not able outside it i.e. not available in NumberFunction function. Also, you were assigning variables in if rather than comparing. = is assignment and == or === is for comparison.
You can improve your code to following:
$(document).ready(function() {
$(".task_hidden").hide();
});
function NumberFunction(random) {
$("#box_" + random).hide();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="row">
<div class="col">
<div class="container text-center">
<div id="box_1" class="random">Box 1</div>
<div id="box_2" class="random">Box 2</div>
<div id="box_3" class="random">Box 3</div>
<div id="box_4" class="random">Box 4</div>
<div id="box_5" class="random">Box 5</div>
<div id="box_6" class="random">Box 6</div>
<div id="box_7" class="random">Box 7</div>
<div id="box_8" class="random">Box 8</div>
<div id="box_9" class="random">Box 9</div>
<div id="box_10" class="random">Box 10</div>
</div>
</div>
<div class="col">
<button onclick="NumberFunction(Math.floor(Math.random() * 10) + 1)" class="mt-5 btn btn-outline-danger">Reveal a random box</button>
</div>
</div>
</div>
Unlike other answers, with each click, a box will be deleted (this is sure to happen) but in other answers may be a few clicks to remove a box.
$(document).ready(function(){
var listOfRemovedNumbers =[];
var lengthBoxs = $('[id^=box_]').length;
function getRandomNumber(){
do {
var randomNumber = Math.floor(Math.random() * 10) + 1;
} while(listOfRemovedNumbers.includes(randomNumber) );
return randomNumber;
}
$('.btn').click(function(){
var randomNumber = getRandomNumber();
$('#box_'+randomNumber).remove();
listOfRemovedNumbers.push(randomNumber);
if ((listOfRemovedNumbers.length == lengthBoxs ))
$('.btn').attr("disabled", "disabled").html('All Removed');
})
})
$(document).ready(function(){
var listOfRemovedNumbers =[];
var lengthBoxs = $('[id^=box_]').length;
function getRandomNumber(){
do {
var randomNumber = Math.floor(Math.random() * 10) + 1;
} while(listOfRemovedNumbers.includes(randomNumber) );
return randomNumber;
}
$('.btn').click(function(){
var randomNumber = getRandomNumber();
$('#box_'+randomNumber).remove();
listOfRemovedNumbers.push(randomNumber);
if ((listOfRemovedNumbers.length == lengthBoxs ))
$('.btn').attr("disabled", "disabled").html('All Boxs are Removed');
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div class="container">
<div class="row">
<div class="col">
<div class="container text-center">
<div id="box_1" class="random">Box 1</div>
<div id="box_2" class="random">Box 2</div>
<div id="box_3" class="random">Box 3</div>
<div id="box_4" class="random">Box 4</div>
<div id="box_5" class="random">Box 5</div>
<div id="box_6" class="random">Box 6</div>
<div id="box_7" class="random">Box 7</div>
<div id="box_8" class="random">Box 8</div>
<div id="box_9" class="random">Box 9</div>
<div id="box_10" class="random">Box 10</div>
</div>
</div>
<div class="col">
<button class="mt-5 btn btn-outline-danger">Reveal a random box</button>
</div>
</div>
</div>
.random {
width: 100px;
height: 100px;
background-color: lightgreen;
margin: 30px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="row">
<div class="col">
<div class="container text-center">
<div id="box_1" class="random">Box 1</div>
<div id="box_2" class="random">Box 2</div>
<div id="box_3" class="random">Box 3</div>
<div id="box_4" class="random">Box 4</div>
<div id="box_5" class="random">Box 5</div>
<div id="box_6" class="random">Box 6</div>
<div id="box_7" class="random">Box 7</div>
<div id="box_8" class="random">Box 8</div>
<div id="box_9" class="random">Box 9</div>
<div id="box_10" class="random">Box 10</div>
</div>
</div>
<div class="col">
<button onclick="NumberFunction(Math.floor(Math.random() * 10) + 1)" class="mt-5 btn btn-outline-danger">Reveal a random box</button>
</div>
</div>
</div>
<script>
function NumberFunction(random) {
$("#box_" + random).hide();
}
</script>

jQuery alternative to nth-child selector that supports classes

I have a structure like this:
<div class="parent">
<div class="randomclass">...</div>
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<div class="randomclassdifferentname">...</div>
<div class="item">Item 4</div>
<div class="item">Item 5</div>
<div class="item">Item 6</div>
<div class="item">Item 7</div>
...
</div>
<div class="parent">
<div class="anotherclass">...</div>
<div class="item">Another item 1</div>
<div class="item">Another item 2</div>
<div>...</div>
<div class="item">Another item 3</div>
...
</div>
I need to select only nth .item div class child of a .parent div (counter resets for every parent node).
For example I want to select every third "div.item" element so I'm expecting to affect elements with content "Item 3", "Item 6", "Another item 3".
Rules:
Desired classes are always applied to a "div" element (maybe not important).
Parents have always "parent" class and are also always "div" elements.
Amongst divs there can be other divs (or any other type of element) with random class name (or without) and these must not interfere with the nth counter.
Elements also can be nested so every item class element can in addition contain another parent class element and that again another item class elements.
Unfortunatelly CSS selector:
div.parent div.item:nth-child(3n)
with nth-child() is not working properly. Although the effects are applied only to elements with given class, the counting itself is not correct because it counts also elements without given class.
As I doubt that there will be pure CSS solution and also because I'm in fact using this as a jQuery selector, I would like some simple jQuery alternative. Thank you guys for any help you can give me.
You can filter the items based on the index they have in the parent, in relation to other items with the same class
$('.item').filter(function(_,item) {
return ($(item).siblings('.item').addBack().index(item)+1) % 3 === 0;
}).css('color','red');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent">
<div class="randomclass">...</div>
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<div class="randomclassdifferentname">...</div>
<div class="item">Item 4</div>
<div class="item">Item 5</div>
<div class="item">Item 6</div>
<div class="item">Item 7</div>
...
</div>
<div class="parent">
<div class="anotherclass">...</div>
<div class="item">Another item 1</div>
<div class="item">Another item 2</div>
<div>...</div>
<div class="item">Another item 3</div>
...
</div>
If you want nth element of some jQuery collection you need to use the .eq() selector on that collection. As in...
var allItems = $('.parent').find('.item');
for (i = 1; i <= allItems.length/3; i++) {
allItems.eq((i*3)-1).css({'border':'1px solid red'})
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent">
<div class="randomclass">...</div>
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<div class="randomclassdifferentname">...</div>
<div class="item">Item 4</div>
<div class="item">Item 5</div>
<div class="item">Item 6</div>
<div class="item">Item 7</div>
...
</div>
<div class="parent">
<div class="anotherclass">...</div>
<div class="item">Another item 1</div>
<div class="item">Another item 2</div>
<div>...</div>
<div class="item">Another item 3</div>
...
</div>
The above will keep your count throughout the collection (irrespective of parents). If you want each parent dealt with separately, use an .each() on $('.parent')s. As in...
$('.parent').each( function(){
var theseItems = $(this).find('.item');
for (i = 1; i <= theseItems.length/3; i++) {
theseItems.eq((i*3)-1).css({border:'1px solid red'})
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent">
<div class="randomclass">...</div>
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<div class="randomclassdifferentname">...</div>
<div class="item">Item 4</div>
<div class="item">Item 5</div>
<div class="item">Item 6</div>
<div class="item">Item 7</div>
...
</div>
<div class="parent">
<div class="anotherclass">...</div>
<div class="item">Another item 1</div>
<div class="item">Another item 2</div>
<div>...</div>
<div class="item">Another item 3</div>
...
</div>
As I doubt that there will be pure CSS solution
For a pure css solution you can utilize General siblings combinator selector ~.
The elements represented by the two sequences share the same parent in
the document tree and the element represented by the first sequence
precedes (not necessarily immediately) the element represented by the
second one.
Use two selectors. At first selector, match required element. At second selector match elements following first selector, set default value for properties set at first matched element or use unset.
/* match third `div.item` */
.parent div.item ~ div.item ~ div.item {
color: sienna;
font-size: 2em;
}
/* match fourth through last `div.item` */
.parent div.item ~ div.item ~ div.item ~ div.item {
color: unset;
font-size: unset;
}
<div class="parent">
<div class="randomclass">...</div>
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<div class="randomclassdifferentname">...</div>
<div class="item">Item 4</div>
<div class="item">Item 5</div>
<div class="item">Item 6</div>
<div class="item">Item 7</div>
...
</div>
<div class="parent">
<div class="anotherclass">...</div>
<div class="item">Another item 1</div>
<div class="item">Another item 2</div>
<div>...</div>
<div class="item">Another item 3</div>
<div class="item">Another item 4</div>
<div class="item">Another item 5</div>
...
</div>
I need to select only nth .item div class child of a .parent div
(counter resets for every parent node).
For example I want to select every third "div.item" element so I'm
expecting to affect elements with content "Item 3", "Item 6",
"Another item 3".
Did not initially notice that requirement was to select every third element.
You can still utilize css General sibling combinator selector with .querySelector(), which returns a single element, within a javascript function to return expected result.
The function currently accepts a parent element as selector string or DOM element, descendant element selector, number referencing the distance between selections of descendant selector, a callback to call for each matched element, returns matched elements within an array.
for loop within for..of loop iterates a maximum of childSelector.length / nth times. A selector string is constructed using the nth number parameter within the for loop; .querySelector() returns the single element, then increments the nth parameter which creates selector matching nth element from previous matched element for next iteration; eliminating the necessity for for loop to iterate all childSelector.length elements of parentSelector to match the required selectors.
const gen = function* (arg) {
yield* arg[Symbol.iterator] ? arg : [arg]
};
window.onload = function() {
// `parentSelector`: `".parent"`, `document.querySelector(".parent")`,
// `document.querySelectorAll(".parent"),
// `document.getElementsByClassName(".parent")`
// `childSelector`: `".item"`; `nth`: `3`; `callback`: function
function nthElement(parentSelector, childSelector, nth, callback) {
let [nthparents, selector, n, items] = [
typeof parentSelector === "string"
? document.querySelectorAll(parentSelector)
: [...gen(parentSelector)]
, childSelector
, nth
, []
];
for (let nthp of nthparents) {
for (let i = n; i <= nthp.querySelectorAll(selector).length; i += n) {
let item = nthp.querySelector(Array(i).fill(selector).join("~"));
items.push(item);
callback.call(item, i, item, nthp)
}
};
return items
}
// select every `nth` third `.item` element
// that is a child of `.parent` element
let items = nthElement(document.querySelectorAll(".parent"), ".item", 3
, function (i, nth, nthParent) {
console.log(i, nth, nthParent);
this.style.color = "sienna";
this.style.fontSize = "2em";
});
console.log(items);
}
<div class="parent">
<div class="randomclass">...</div>
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<div class="randomclassdifferentname">...</div>
<div class="item">Item 4</div>
<div class="item">Item 5</div>
<div class="item">Item 6</div>
<div class="item">Item 7</div>
...
<div class="randomclass">...</div>
<div class="randomclass">...</div>
<div class="randomclass">...</div>
<div class="item">Item 8</div>
</div>
<div class="parent">
<div class="anotherclass">...</div>
<div class="item">Another item 1</div>
<div class="item">Another item 2</div>
<div>...</div>
<div class="item">Another item 3</div>
<div class="anotherclass">...</div>
<div class="item">Another item 4</div>
<div class="item">Another item 5</div>
...
<div class="anotherclass">...</div>
<div class="anotherclass">...</div>
<div class="anotherclass">...</div>
<div class="item">Another item 6</div>
</div>
Using jQuery
$(function() {
function nthElement(childSelector, nth, callback) {
let [nthparents, selector, n, items] = [
Array.from(this)
, childSelector
, nth
, []
];
for (let nthp of nthparents) {
for (let i = n; i <= nthp.querySelectorAll(selector).length; i += n) {
let item = nthp.querySelector(Array(i).fill(selector).join("~"));
items.push(item);
callback.call(item, i, item, nthp)
}
};
return jQuery(items)
}
// set `nthElement` as a jQuery method
$.fn.extend({nthElement: nthElement});
// select every third `.item` element that is a child of `.parent` element
var items = $(".parent").nthElement(".item", 3, function(i, nth, nthParent) {
console.log(i, nth, nthParent);
$(this).css({color: "sienna",fontSize: "2em"});
});
console.log(items);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<div class="parent">
<div class="randomclass">...</div>
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<div class="randomclassdifferentname">...</div>
<div class="item">Item 4</div>
<div class="item">Item 5</div>
<div class="item">Item 6</div>
<div class="item">Item 7</div>
...
<div class="randomclass">...</div>
<div class="randomclass">...</div>
<div class="randomclass">...</div>
<div class="item">Item 8</div>
</div>
<div class="parent">
<div class="anotherclass">...</div>
<div class="item">Another item 1</div>
<div class="item">Another item 2</div>
<div>...</div>
<div class="item">Another item 3</div>
<div class="anotherclass">...</div>
<div class="item">Another item 4</div>
<div class="item">Another item 5</div>
...
<div class="anotherclass">...</div>
<div class="anotherclass">...</div>
<div class="anotherclass">...</div>
<div class="item">Another item 6</div>
</div>
nth-child selector is not class sensitive. It selects element by name not by class. See jquery nth-child
The :nth-child(n) pseudo-class is easily confused with :eq(n), even though the two can result in dramatically different matched elements. With :nth-child(n), all children are counted, regardless of what they are, and the specified element is selected only if it matches the selector attached to the pseudo-class. With :eq(n) only the selector attached to the pseudo-class is counted, not limited to children of any other element, and the (n+1)th one (n is 0-based) is selected.
Though eq(n) is class sensitive but it not supports equation as parameter.
So I think there's no direct way to use css only to implement it.
Try it also with some js codes.
This isn't possible with pure CSS selectors. However, this is something achievable if you have the flexibility to use a unique tag name instead of div.item. Here is something you could do, if you could change the div.item elements to a p tag.
.parent p:nth-of-type(3n) {
color: red;
}
.parent {
padding: 10px;
border: 1px solid black;
}
.item {
border: 1px dotted black;
}
<div class="parent">
<div class="randomclass">Random</div>
<p class="item">Item 1</p>
<p class="item">Item 2</p>
<p class="item">Item 3</p>
<div class="randomclassdifferentname">Random different Name</div>
<p class="item">Item 4</p>
<p class="item">Item 5</p>
<p class="item">Item 6</p>
<p class="item">Item 7</p>
</div>
<div class="parent">
<div class="anotherclass">Another Random</div>
<p class="item">Another item 1</p>
<p class="item">Another item 2</p>
<div>Random Text</div>
<p class="item">Another item 3</p>
</div>

Bootstrap well same height

I use the bootstrap class well for decoration. I have two divs with different amount of entries inside. Is it possible that both wells fill their parent and have always the same height no matter how many entries they contain?
<div class="container">
<div class="row">
<div class="col-xs-8">
<strong>Title</strong>
<div class="well well-sm">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
<div>Item 5</div>
<div>Item 6</div>
</div>
</div>
<div class="col-xs-4">
<strong>Title</strong>
<div class="well well-sm">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>
</div>
</div>
</div>
I tried different solutions but didn’t succeed. I want to avoid the flex box layout because of its weak support. If I use tables instead of bootstrap columns I get the same result. How can I handle this with CSS (and possibly without adding JavaScript) ?
jsfiddle
I use this solution for that problem
Without JavaScript.
I found it on this link.
<div class="row row-flex row-flex-wrap">
//Your well code
</div>
UPDATE
and add this css:
.row-flex, .row-flex > div[class*='col-'] {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
flex:1 1 auto;
}
.row-flex-wrap {
-webkit-flex-flow: row wrap;
align-content: flex-start;
flex:0;
}
.row-flex > div[class*='col-'], .container-flex > div[class*='col-'] {
margin:-.2px; /* hack adjust for wrapping */
}
.container-flex > div[class*='col-'] div,.row-flex > div[class*='col-'] div {
width:100%;
}
.flex-col {
display: flex;
display: -webkit-flex;
flex: 1 100%;
flex-flow: column nowrap;
}
.flex-grow {
display: flex;
-webkit-flex: 2;
flex: 2;
}
Hope this will helpfull.
JavaScript:
If you are okay with using a little bit of JavaScript then the following will be exactly what you need:
var
elements = document.querySelectorAll(".well"),
heights = [];
/* Getting an array with the heights */
[].forEach.call(elements, function(each) {
heights[heights.length] = getComputedStyle(each, null).getPropertyValue("height");
});
/* Sorting the array to get the greatest value first */
heights.sort(function(a, b) {
return parseFloat(b) - parseFloat(a);
});
/* Applying the greatest height to each element */
[].forEach.call(elements, function(each) {
each.style.height = heights[0];
});
jQuery:
If instead you're in for shorter code and you use jQuery you can use the following code:
var max;
/* Getting the greatest height */
$(".well").each(function() {
max = ($(this).height() > max) ? $(this).height() : max;
});
/* Applying the greatest height to each element */
$(".well").height(max);
Execution times:
JavaScript: 0.562ms
jQuery: 2.889ms (~5x slower)
Here's a snippet demonstrating the solution:
/* ----- JavaScript ----- */
var
elements = document.querySelectorAll(".well"),
heights = [];
[].forEach.call(elements, function(each) {
heights[heights.length] = getComputedStyle(each, null).getPropertyValue("height");
});
heights.sort(function(a, b) {
return parseFloat(b) - parseFloat(a);
});
[].forEach.call(elements, function(each) {
each.style.height = heights[0];
});
/* ----- CSS ----- */
.well {
border: 1px solid blue !important;
}
<!----- HTML ----->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
rel="stylesheet" type="text/css" />
<div class="container">
<div class="row">
<div class="col-xs-8">
<strong>Title</strong>
<div class="well well-sm">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
<div>Item 5</div>
<div>Item 6</div>
</div>
</div>
<div class="col-xs-4">
<strong>Title</strong>
<div class="well well-sm">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>
</div>
</div>
</div>
You can set another class to the divs if you have the exact height size value you want it to have:
<div class="container">
<div class="row">
<div class="col-xs-8">
<strong>Title</strong>
<div class="well well-sm test">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
<div>Item 5</div>
<div>Item 6</div>
</div>
</div>
<div class="col-xs-4">
<strong>Title</strong>
<div class="well well-sm test">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>
</div>
</div>
</div>
And for example if your max height value is 300px (or can be min-height):
.test {
height: 300px !important;
}
It will be the same size, jsFiddle
But! if you want to make it the same height, without having a fixed height value, then I think you'd need to use javascript to get the biggest's divs height.
Take an example here:
How to set height of element to match height of another element?
There's a very quick snippet I made for you using jQuery, it's made pretty badly, i am sure there are better and short ways:
var max = 0;
$.each( $('.row > div > div'), function(i, row) {
var cheight = $(row).height();
if (cheight > max) {
max = cheight;
}
})
$.each( $('.row > div > div'), function(i, row) {
$(row).height(max);
})
jsFiddle here
Here is the answer with jQuery https://jsfiddle.net/mjgLufa1/1/
var maxHeight = 0;
$(".row").each(function() {
if ($(this).height() > maxHeight) {
maxHeight = $(this).height();
}
});
$(".well ").height(maxHeight);
.well{
border: 1px solid red !important;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" type="text/css"/>
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" > </script>
<body>
<div class="container">
<div class="row">
<div class="col-xs-8">
<strong>Title</strong>
<div class="well well-sm">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
<div>Item 5</div>
<div>Item 6</div>
</div>
</div>
<div class="col-xs-4">
<strong>Title</strong>
<div class="well well-sm">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 3</div>
<div>Item 3</div>
<div>Item 3</div>
</div>
</div>
</div>
</div>
</body>
Try use .row-eq-height.
<div class="row row-eq-height">
...
</div>
Note this example: http://getbootstrap.com.vn/examples/equal-height-columns/
Might be useful in your case.

Categories

Resources