Apply style to first div with specific class in DOM - javascript

I have a reusable accordion component but what I'm trying to achieve is for the first accordion to have a greater padding set, compared to the others. Can this be achieved via CSS? If not, what's the best way to achieve this via jQuery/JS.
Note: I can't just add a class to the first section, as I've stated, it's a reusable component, so the markup is always the same.
<!-- Apply padding to this section only -->
<section class="accordion-wrapper">
<p>Some content in here</p>
</section>
<section class="accordion-wrapper">
<p>Some content in here</p>
</section>
<section class="accordion-wrapper">
<p>Some content in here</p>
</section>
<section class="accordion-wrapper">
<p>Some content in here</p>
</section>

Update: first-of child won't work and I have updated the answer
You can achieve this way by a workaround with pure CSS: select every element of the class that is the sibling of the same class -> invert it, -> select by the class again.
Working Codepen: https://codepen.io/tusharg09/pen/oNoOxrq
:not(.accordion-wrapper ~ .accordion-wrapper).accordion-wrapper {
color: red;
}
<section class="accordion-wrapper">
<p>Some content in here</p>
</section>
<section class="accordion-wrapper">
<p>Some content in here</p>
</section>
<section class="accordion-wrapper">
<p>Some content in here</p>
</section>
<section class="accordion-wrapper">
<p>Some content in here</p>
</section>

Assuming that accordion sections are the only children of some parent element it can be done via css. You can use first-child pseudo class:
.accordion-wrapper:first-child {
...
}

While in the simple cases you may be able to use CSS only, for a general solution which works whatever the HTML structure is, you need to use a bit of JS.
This snippet finds the very first occurence of the element with that class in the whole document. It then adds another class to it which sets the padding.
<!doctype html>
<html>
<head>
<style>
.accordion-wrapper.extra {
padding: 10px;
}
</style>
</head>
<body>
<!-- Apply padding to this section only -->
<section class="accordion-wrapper">
<p>Some content in here</p>
</section>
<section class="accordion-wrapper">
<p>Some content in here</p>
</section>
<section class="accordion-wrapper">
<p>Some content in here</p>
</section>
<section class="accordion-wrapper">
<p>Some content in here</p>
</section>
<script>
const first = document.querySelector('.accordion-wrapper');
first.classList.add('extra');
</script>
</body>
</html>
UPDATE: since giving the answer above, I've seen the HTML structure for this specific question and that can be solved by CSS only using:
main section:first-of-type
as the selector. Just be aware that if the structure changes it may not be right, as indeed the first answer may not be if other such sections are put in above main.
It is perhaps safest to combine the two approaches and in the JS select the first section within main. Depends on the actual use case of course.

Well there are several ways to achieve this. Since you try to build an accordion so you basically know which of your accordion keys will be different shaped, right?
Therefore you can use for example, assigning a second class to your div. Or another way would be, :nth-child() like every second or third key will be shaped in another way. You can find the example code snippet outside of the Code itself.
.accordion-wrapper {
display:flex;
flex-direction: column;
}
.accordion-key {
border: 1px solid #333;
padding: 5px 0 5px 10px;
}
.accordion-keyBlack {
background-color: #111;
color: #fff;
padding: 10px 0 10px 20px;
}
<div class="accordion-wrapper">
<div class="accordion-key">A</div>
<div class="accordion-key accordion-keyBlack">B</div>
<div class="accordion-key">C</div>
<div class="accordion-key">D</div>
<div class="accordion-key">E</div>
</div>
or you can use :nth-child() for example to define that every second key is black or whatever. Further read, here: https://developer.mozilla.org/de/docs/Web/CSS/:nth-child
.accordion-key:nth-child(2n) {
background-color: #111;
color: #fff;
padding: 10px 0 10px 20px;
}
Of course you can use JS as well, but therefore we would need more details, like the logic of key-arrangement itself.

Select first div with specific class is not possible with CSS. The closest result is:
section {
padding: 10px;
margin: 10px;
background: red;
}
.accordion-wrapper:first-child,
:not(.accordion-wrapper) + .accordion-wrapper {
padding: 10px;
background: yellow;
}
<section class="something-random"></section>
<!-- first div with class is here -->
<section class="accordion-wrapper"></section>
<section class="accordion-wrapper"></section>
<section class="accordion-wrapper"></section>
<section class="accordion-wrapper"></section>
<section class="accordion-wrapper"></section>
It selects first child .accordion-wrapper:first-child or an element that is not preceded by an element with the same class :not(.accordion-wrapper) + .accordion-wrapper.
Problem of this approach is this case:
section {
padding: 10px;
margin: 10px;
background: red;
}
.accordion-wrapper:first-child,
:not(.accordion-wrapper) + .accordion-wrapper {
padding: 10px;
background: yellow;
}
<section class="something-random"></section>
<!-- first div with class is here -->
<section class="accordion-wrapper"></section>
<section class="accordion-wrapper"></section>
<section class="accordion-wrapper"></section>
<section class="accordion-wrapper"></section>
<section class="accordion-wrapper"></section>
<section class="something-random"></section>
<!-- but this is not first with class -->
<section class="accordion-wrapper"></section>
<section class="accordion-wrapper"></section>
<section class="accordion-wrapper"></section>

Related

JS: Adding style dependent on class exist in siblings child

I've had a look at related answers but none are what I am looking for... I think. Apologies if I am duplicating a question.
This HTML is used many times on a page, within a product box and is displayed on a product category page.
<div class"all-buttons-container">
<div class="button1-container">
<a class="button1">text</a>
</div>
<div class="button2-container">
<a class="button2 **hidden**">text</a>
</div>
</div>
In this (much simplified) HTML I have a container which houses 2 siblings.
- Each sibling contains an anchor.
The button containers are always visible.
Sometimes, the .button2 anchor also has the bootstrap class of hidden so the anchor is no longer displayed. This is done in each of the product boxes depending on the need to have the second button for that product. I am not in control of this.
When the .button2 anchor has the hidden class I need to add some margin-top to button1-container to vertically center it
I was going to use pure style (flexbox) but it wasn't achieving what I needed.
I would like to run a little jQuery or pure JS every time the page finishes loading which adds some the top margin, if required, on each instance of this HTML. I don't like having to do this but will need to if I cannot find another simple way of controlling it.
Any thoughts... solutions... perfect solutions etc?
Thanks in advance!
cheers
wayjo
I suppose I've fully understood your question.
You can achieve this without JS, in a cleaner any.
Why not make a custom class of button2-hidden and attach it to all-buttons-container?
<div class"all-buttons-container button2-hidden">
<div class="button1-container">
<a class="button1">text</a>
</div>
<div class="button2-container">
<a class="button2">text</a>
</div>
</div>
Then you have this CSS:
.button2-hidden .button2-container{
display: none; // or visibility -- whatever you want
}
.button2-hidden .button1-container{
margin-top: 1rem;
}
If you can add a div to contain the buttons, than you can use the snippet below:
.all-buttons-container{
display: flex; /* important part */
align-items: center; /* important part */
padding: 10px;
background-color: grey;
width: 200px;
border: 2px solid #fff;
height: 150px;
}
.hidden {
display: none!important;
}
.all-buttons-container > div a{
display: inline-block;
background-color: blue;
padding: 7px;
margin: 7px;
color: #fff;
}
<div class="all-buttons-container">
<div class="very-important-div">
<div class="button1-container">
<a class="button1">button1</a>
</div>
<div class="button2-container">
<a class="button2">button2</a>
</div>
</div>
</div>
<div class="all-buttons-container">
<div class="very-important-div">
<div class="button1-container">
<a class="button1">button1</a>
</div>
<div class="button2-container">
<a class="button2 hidden">button2</a>
</div>
</div>
</div>
<div class="all-buttons-container">
<div class="very-important-div">
<div class="button1-container">
<a class="button1 hidden">button1</a>
</div>
<div class="button2-container">
<a class="button2">button2</a>
</div>
</div>
</div>

How to recreate mac scrollbar fade in and out when scrolling starts in css

I am starting with this:
*::-webkit-scrollbar {
}
*::-webkit-scrollbar-button {
}
*::-webkit-scrollbar-track {
}
*::-webkit-scrollbar-track-piece {
}
*::-webkit-scrollbar-thumb:active {
width: 6px;
background-color: red;
}
*::-webkit-scrollbar-corner {
}
*::-webkit-resizer {
}
How do I go about recreating the functionality of animating/fading-in the scrollbar only when you start scrolling, and then when you hover over the scrollbar, it gets wider. Right now if I try to style it using these methods, it is permanently present. Do I need custom JavaScript to do this or is there another way?
I just want to change the background image of all the scrollbars, but have it still work like all the existing mac scrollbars.
I don't have a pure CSS solution for you, I tend to do this in JS with the use of a custom scrollbar library (not affiliated with me).
Once the library is added you can simply use the following jQuery to initialise it:
$('.container').mCustomScrollbar({
theme: "dark-3", // some theme examples: http://manos.malihu.gr/repository/custom-scrollbar/demo/examples/scrollbar_themes_demo.html
autoExpandScrollbar: true, //options list can be found here http://manos.malihu.gr/jquery-custom-content-scroller/#configuration-section
autoHideScrollbar: true
});
Here's a working example below:
$('.container').mCustomScrollbar({
theme: "dark-3",
autoExpandScrollbar: true,
autoHideScrollbar: true
});
.container {
width: 200px;
height: 100px;
overflow: hidden;
background-color: #fafafa;
padding: 10px;
border: 1px solid black;
}
.container p {
margin: 5px 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/malihu-custom-scrollbar-plugin/3.1.5/jquery.mCustomScrollbar.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/malihu-custom-scrollbar-plugin/3.1.5/jquery.mCustomScrollbar.css" rel="stylesheet" />
<div class="container">
<p>This is a test 1</p>
<p>This is a test 2</p>
<p>This is a test 3</p>
<p>This is a test 4</p>
<p>This is a test 5</p>
<p>This is a test 6</p>
<p>This is a test 7</p>
<p>This is a test 8</p>
<p>This is a test 9</p>
<p>This is a test 10</p>
<p>This is a test 11</p>
<p>This is a test 12</p>
<p>This is a test 13</p>
<p>This is a test 14</p>
<p>This is a test 15</p>
<p>This is a test 16</p>
<p>This is a test 17</p>
</div>

Remove styles from one div if other div's styles are active

I'm looking for a help with a small things to do on my CMS website.
I would like to know, if it's possible, how to to remove or hide styles from one div one a website while another div is active and only when this 2nd div is inside the first one.
I'm using easytabs jQuery plugin and easytabs html code is inserted in tinymce WYSIWYG HTML source editor, while <div class="block"></div> is generated from CMS, because it's a wrapper of content module.
Let me show you my code so maybe you can understand more what I want to do:
<div class="block">
<div id="tab-container" class="tab-container">
<ul class='etabs'>
<li class='tab'>HTML Markup</li>
<li class='tab'>Required JS</li>
<li class='tab'>Example CSS</li>
</ul>
<div id="tabs1-html">
<h2>HTML Markup for these tabs</h2>
<!-- content -->
</div>
<div id="tabs1-js">
<h2>JS for these tabs</h2>
<!-- content -->
</div>
<div id="tabs1-css">
<h2>CSS Styles for these tabs</h2>
<!-- content -->
</div>
</div>
</div>
<div class="block">
<div class="test">
</div>
</div>
Okay, so CMS is adding <div class="block"></div> with a styles
(thats are the styles):
#main .block {
border: 2px solid #e0e0e0;
padding: 24px 28px 24px 26px;
margin: 0 0 8px;
background: #ffffff;
text-align: justify;
overflow: auto;
}
And here comes the problem. I would like to remove or hide styles from this <div class="block"></div> element only while I have <div id="tab-container" class="tab-container"></div> inside this div <div class="block"></div>.
And I need to keep all the styles for <div class="block"></div> when I have other divs inside it.
Is it doable with some jQuery or JS ? Or it's not possible ?
Thanks in advance.
You can do this with the has() function within jQuery. You're going to have to reset or change each of the CSS values
$(document).ready(function() {
$('.block').has('#tab-container.tab-container').css('border', '0');
});
.block {
border: 2px solid red;
margin-bottom: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="block">
<div class="some_tag">
Text
</div>
</div>
<div class="block">
<div id="tab-container" class="tab-container">Some more text</div>
</div>
You can do an array of CSS values as well if there is more than one that needs to be changed like so:
.css({ "border": "0", "background": "blue"})
Insteed of resetting or overwritte all block classes maybe it would be much easier to add:
$(document).ready(function () {
$('.block').has('div.tab-container').removeClass('block');
});
This way you will remove the block class so no styles.
JSFIDDLE

Show table when its tab is clicked but hide other tables

So right now I have a section that has 3 tabs on it. Each tab is supposed to bring up a different table while simultaneously hiding the other 2 tables. When the page loads up it shows the first table (which it is supposed to do), but when I click one of the other two tabs nothing happens. I realize this has to be done with a Javascript onclick but I'm not familiar with it yet to know what I'm doing. I unfortunately have a lot of code that goes into making this work so i wont be able to post it on here but ill grab the code i think is most important and if you need any more info let me know. Please and thankyou for your help.
The tabs are "Pavement Section Editor", "Traffic", and "Condition"
HTML:
<div class='row' style="background-color: white; vertical-align:top; height: 250px;">
<div class="fifthDiv">
<br />
<article style="float: left; width: 100%; margin-left: 25px; height:250px;">
<section class="tabSection" id="tabmain">
<h2 class="large" style="font-size: 12px;">
Pavement Section Grid
</h2>
<p><div id="table_div_Main"></div></p>
</section>
#foreach (var layer in lstLayers)
{
if (layer != "Pavement Section" && layer != "Cores" && layer != "Inventory")
{
<section id="#("tab" + layer.Replace(" ", ""))" class="tabSection">
<h2 class="medium" style="font-size: 12px;">#layer</h2>
<p><div id="#("table_div_" + layer.Replace(" ", ""))"></div></p>
</section>
}
}
</article>
</div>
</div>
JAVASCRIPT:
function drawSectionData(data) {
return drawMe(data, 'Pavement Section Data', 'table_div_Main');
};
function drawTrafficData(data) {
return drawMe(data, 'Traffic Data', 'table_div_Traffic');
};
function drawConditionData(data) {
return drawMe(data, 'Condition Data', 'table_div_Condition');
};
//what i got so far on the javascript
$(".tabSection").children("h2").on('click', function() { console.log(this.closest("section")); })
The best way to implement tabs in your scenatio is to use jQuery Tabs - very easy and almost no additional coding required, and as added benfit it is free
Based on the assumption that:
You want to hide only the content that sits within the p of each
section and not hide the whole section itself because that would
mean that your click-able h2 will also become invisible.
You have removed div from within your section and are only using p
because inline elements do not allow to contain a block (in your
case, a div) element inside it. [Link], [Link] & [Link].
Your JavaScript code then may look like this:
var tabSections=$('.tabSection'); // select all .tabSection elements
tabSections.not('#tabmain').find('p').hide(); // hide all p elements found within tabSections stored above excluding #tabmain
tabSections.find('h2').on('click',function(){ // assign clicks to all h2 elements found within tabSections
tabSections.find('p').hide(); // hide all p elements found within tabSections
$(this).siblings('p').show(); // show the p element which is a sibling to the clicked h2 element
});
Snippet:
var tabSections=$('.tabSection');
tabSections.not('#tabmain').find('p').hide();
tabSections.find('h2').on('click',function(){
tabSections.find('p').hide();
$(this).siblings('p').show();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div class='row' style="background-color: white; vertical-align:top; height: 250px;">
<div class="fifthDiv">
<br />
<article style="float: left; width: 100%; margin-left: 25px; height:250px;">
<section class="tabSection" id="tabmain">
<h2 class="large" style="font-size: 12px;">
Main
</h2>
<p id="table_div_Main">Pavement Data</p>
</section>
<section class="tabSection" id="tabTraffic">
<h2 class="medium" style="font-size: 12px;">
Traffic
</h2>
<p id="table_div_Traffic">Traffic Data</p>
</section>
<section class="tabSection" id="tabCondition">
<h2 class="medium" style="font-size: 12px;">
Condition
</h2>
<p id="table_div_Condition">Condition Data</p>
</section>
</article>
</div>
</div>
Hope this helps.

jQuery: Add styling to tag if it exists above self

I want to .addClass("someClass" to <blockquote> if it has a <figure> with class hello above it, like this:
<figure class="hello"> world </figure>
<blockquote> Lorem </blockquote>
So, only if the <figure> tag is right above it, not if something is separating the tags like a div.
Is such thing possible?
Assuming this is to style the <blockquote> element when it is immediately preceded by a <figure>, then you can simply use CSS:
figure + blockquote {
border-color: red; /* or whatever */
}
section {
border: 1px solid #000;
margin: 0 0 1em 0;
}
blockquote {
border: 1px solid #000;
}
figure + blockquote {
border-color: #f00;
}
<section>
<figure>This is a figure</figure>
<blockquote>And this is an immediately-following blockquote.</blockquote>
</section>
<section>
<blockquote>This is a blockquote.</blockquote>
<figure>And this is a figure following a blockquote</figure>
</section>
<section>
<figure>Another figure</figure>
<div>a div</div>
<blockquote>And this is a blockquote.</blockquote>
</section>
References:
Adjacent-sibling (+) combinator.
$('figure.hello + blockquote').addClass('someClass');
From jQuery's docs:
Next Adjacent Selector (“prev + next”)
Selects all next elements matching "next" that are immediately
preceded by a sibling "prev".
Can work from the known class ...is simplest
$('figure.hello').next('blockquote').addClass("someClass");
The way it works is if either selector isn't found, nothing happens and will only work for figure with folloing sibling being a blockuote

Categories