33

I want to select only <buttons> whose parents have display: block and exclude those <buttons> whose parents have display:none.

Is there any way to accomplish this?

cнŝdk
  • 31,391
  • 7
  • 56
  • 78
alex
  • 7,111
  • 15
  • 50
  • 77

6 Answers6

37

Actually there's a CSS3 solution to select elements that doesn't have a display:none style, or given an explicit style property:

*:not([style*="display: none"]) button{ ... }

Demo:

*:not([style*="display: none"]) button{
    color:yellow;
}
<p style="display:block">
  My name is A.
  <button>
a
</button>
</p>
<p style="display: none">
  <button>
b
</button>
</p>
cнŝdk
  • 31,391
  • 7
  • 56
  • 78
23

If those display styles are declared inline then you can use the following selectors: div[style*="display: none;"] (if element has inline style attribute containing "display: none;" then apply style)

Attribute Selectors:

The CSS attribute selector matches elements based on the presence or value of a given attribute.

Src: https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors

Attribute Contains Selector:

When looking to find an element based on part of an attribute value, but not an exact match, the asterisk character, *, may be used within the square brackets of a selector. The asterisk should fall just after the attribute name, directly before the equals sign. Doing so denotes that the value to follow only needs to appear, or be contained, within the attribute value.

Src: https://learn.shayhowe.com/advanced-html-css/complex-selectors/

UncaughtTypeError
  • 8,226
  • 4
  • 23
  • 38
3

No.

There are no selectors which select elements based on the values of properties that apply to them.


I don't think it would be practical for CSS to introduce such a feature either. Imagine:

:has-property-value(display: none) {
   display: block;
}
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
2

This is not possible with pure CSS so far, Unless you explicitly specify the inline css to style="display: none".

You could use some javascript to filter a set of buttons that are visible.

var buttons = document.querySelectorAll('.block button');

var visibleButtons = [];

buttons.forEach(function (element) {
  if (window.getComputedStyle(element.parentNode).display !== 'none') {
   visibleButtons.push(element);
  }
});

console.log(visibleButtons);
.block {
  display: block;
}

.hidden {
  display: none;
}
<div class="block">
  <button>btn 1</button>
</div>

<div class="block hidden">
  <button>btn 2</button>
</div>

<div class="block">
  <button>btn 3</button>
</div>
Jose Paredes
  • 3,882
  • 3
  • 26
  • 50
  • Actually [**it's possible with CSS3**](https://stackoverflow.com/a/46787219/3669624) to select elements using a style property. – cнŝdk Oct 17 '17 at 09:47
  • @cнŝdk Not really since the solution you link to requires inline styling. The poster, however, offers a universal solution as it works with computed style regardless with it is declared inline or in a head CSS element. – DDRRSS Dec 28 '21 at 17:28
1

There are no such selector available in CSS to select by their property values. You can try something with jquery by using :hidden selector to find buttons with display:none. Check below snippet for reference.

$( ".btnShow" ).click(function() {
  $( ".btn:hidden" ).show( "fast" );
});
.hidden{
  display:none;
}
.btnShow{
  display:block;
  margin-top: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="button" value="button 1" class="btn">
<input type="button" value="button 2" class="btn">
<input type="button" value="button 3" class="btn hidden">
<input type="button" value="button 4" class="btn">
<input type="button" value="button 5" class="btn hidden">
<input type="button" value="button 6" class="btn">
<input type="button" value="button 7" class="btn">
<input type="button" value="Show hidden buttons" class="btnShow">
RaJesh RiJo
  • 4,302
  • 4
  • 25
  • 46
-3

You can check with jquery. The code below means

"Get all buttons, filtered by ones whose parent is visible on page", loop through and print html of each one.

$(document).ready(function(){
$(":button").filter(function() { return $(this).parent().is(':visible') 
       }).each(function(){
        console.log($(this).html());
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p class="intro" style="display:block">
    My name is someone.    
   <button>    a    </button>    <button>    b    </button>    
</p>
<p>I live somewhere.</p>    <p>My best friend is someone.</p>
Who is your favourite:    
<ul id="find" style="display:none">
  <li>One</li>      <li>Two</li>      <li><button>    x    </button>    
  <button>    y    </button></li>    
</ul>
Amit Kumar Singh
  • 4,393
  • 2
  • 9
  • 22