How do I choose a class by targeting divs of certain IDs within those classes?

css

#1

I have two divs of class pagediv. Inside are divs (#myDIV1, #myDIV2) for innerHTML injection.

I'd like to turn the other pagedivs to display:none when a button in the one pagediv is selected. This will be similar to an SPA operation of hiding all the other divs to show just the page selected. Then clicking (tapping) another button will remove all display:none to show all the buttons again. Simplified example:

    <div class="pagediv">
        <button id="ItemA" class="buttonItem" onclick="showItemA()">A</button>
	<div id="myDIV1" class="box"></div> 
    </div> 

    <div class="pagediv">
        <button id="ItemE" class="buttonItem" onclick="showItemE()">E</button>
	<div id="myDIV2" class="box"></div> 
    </div>

The best css I can come up with is this.
.pagediv :not(#myDIV2) {display:none;}
.pagediv #myDIV2 {display:block;}

Unfortunately, it hides all the buttons for both pagedivs rather than just the pagediv button containing myDIV1. I suspect I am supposed to use > or < in the CSS some way, but I haven't found the reference page for these yet. If it's on this page, I missed it: https://www.w3.org/TR/css-2017/#selectors

Once I can get the CSS right, then I'll work on trying to implement that in a JS function. In case you want to know the context, I expect to integrate the CSS and function into this codepen: https://codepen.io/iPhoneDevLog/pen/rvJQYg


#2

What you're looking for here is the parent selector, and it doesn't exist.

You can only solve this with javascript by querying for ItemA or ItemE, and then getting the closest parent with class pagediv


#3

I need to rethink my approach then. I suppose I could put the button's parent selector ID in the DB as I did the innerHTML ID. Calling one will call the other.


#4

Have you considered this approach:

<html>
	<head>
		<title> </title>
		
		<style type="text/css" media="screen">
			.container {
				position: relative;
				overflow: hidden;
             }
			.container > input{
				/*hides input*/
				position: absolute;
 				left :-99999em;
				top :-99999em;
			}
			 label.buttonItem{
				 border-radius: .375em;
				 color:#777;
				 background: #ccc;
 				 padding: .5em 1em;
 				 display: inline-block;
			 }
			.container .box { display:none; border: 1px solid ; padding: .25em; margin-top: .5em}
			#ItemA:checked ~ #myDIV1, #ItemB:checked ~ #myDIV2,  #ItemC:checked ~ #myDIV3   {  /*little heavy handed using 2 IDs and a pseudo class, but this is for proof of concept  only*/
 				display:block;
			}			
		</style>
	</head>
	
	<body>
		    <div class="container">
			 	<input type="radio" id="ItemA" name="myDivs" checked="checked">    
			 	<input type="radio" id="ItemB" name="myDivs">    
			 	<input type="radio" id="ItemC" name="myDivs">    
			 	<label for="ItemA" class="buttonItem" >Item A</label>
			 	<label for="ItemB" class="buttonItem" >Item B</label>
			 	<label for="ItemC" class="buttonItem" >Item C</label>
				<div id="myDIV1" class="box"> Content A  </div> 
				<div id="myDIV2" class="box"> Content B  </div> 
				<div id="myDIV3" class="box"> Content C  </div> 
			</div> 
 	</body>
</html>

Plus is js free.

Hope that helps.


#5

OK, this issue was resolved. Codepen in #4 was updated.


#6

I am going the DB route because I expect to swap out information among apps and use the same infrastructure.


#7

For those that come after, another option, as i've had to fight this before in other closed-environment situations:

Hidden Inputs.

    <input type='hidden' class='selectedinput' name='selecteditem' value='A'>
    <div class="pagediv pagedivA">
        <button id="ItemA" class="buttonItem" onclick="showItemA()">A</button>
	<div id="myDIV1" class="box"></div> 
    </div> 
    <div class="pagediv pagedivE">
        <button id="ItemE" class="buttonItem" onclick="showItemE()">E</button>
	<div id="myDIV2" class="box"></div> 
    </div>

This now gives me an element that is a sibling of the target elements.
CSS:

pagediv {
   display: none;
}
.selectedinput[value="A"] ~ .pagedivA,
.selectedinput[value="E"] ~ .pagedivE {
   display: block;
}

(oversimplified)

and then have your showItem code simply set the value of the selecteditem input.


#8

Sounds like the :target selector might do the trick, so you can emulate some basic routing (that can also be bookmarked)... like e.g.

.box {
  display: none;
}

.page-div:target > .box {
  display: block;
}

<div class="page-div" id="item-1">
  <a href="#item-1">select item 1</a>
  <div class="box">Item 1</div>
</div>

<div class="page-div" id="item-2">
  <a href="#item-2">select item 2</a>
  <div class="box">Item 2</div>
</div>

<div class="page-div" id="item-3">
  <a href="#item-3">select item 3</a>
  <div class="box">Item 3</div>
</div>

... or with a nav menu of sorts...

.page-div {
  display: none;
}

.page-div:target {
  display: block;
}

.page-div:target ~ .menu {
  display: none;
}

<div class="page-div" id="item-1">
  <div class="box">Item 1</div>
  <a href="#">back</a>
</div>

<div class="page-div" id="item-2">
  <div class="box">Item 2</div>
  <a href="#">back</a>
</div>

<div class="page-div" id="item-3">
  <div class="box">Item 3</div>
  <a href="#">back</a>
</div>

<ul class="menu">
  <li><a href="#item-1">select item 1</a></li>
  <li><a href="#item-2">select item 2</a></li>
  <li><a href="#item-3">select item 3</a></li>
</ul>

fiddle

Out of curiosity, what would be the advantage over doing this with JS alone? I mean you still need the JS, plus a lot of copy/paste in the CSS that has to reflect the values set by JS...


#9

I mean.. your JS at that point is reduced to "document.getElementById("hiddenfield").value = 'A'", so its readability has gotta be pretty strong.

It can definitely lead to some extended CSS (if you have a lot of values that the input could be). If you're doing it with a couple of fixed values, not as much.

EDIT: Also i've realized the environment my example was working in was also running scripts (beyond my control) that automatically replaced values of same-name fields, so in my environment <select name='selecteditem'><option>A</option><option>E</option></select> would have done all the work for you. Not true in a standard environment (though it would be mightily handy if it was)


#10

Hm... I'd argue that the opposite is the case; like, when you toggle a class you can search for that class name in the CSS, but here it's not immediately obvious how this relates to CSS (or that it does in the first place). Anyway, thanks for clarifying! :-)


#11

I am satisfied with my progress. Thanks to everyone who helped!


#13

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.