Hide only direct text children, not element children in CSS - html

I have a ul list and would like to hide all the text that is not inside an anchor. This is markup from a CMS so I can't add in additional selectors...
<ul class="list">
<li class="sub">
link not linked
</li>
</ul>
I have tried using the following css but it doesn't work.
.list .sub:not(a) {
display: none;
}
Why doesn't this work?
Jsfiddle: http://jsfiddle.net/9tg0g44e/

.sub:not(a) matches any element with the class .sub if it's not an a element.
Since the .sub here is a li, it's not an a, so that hides the li and all its contents.
Normally, to select any children of .sub that aren't a elements, you'd use .sub > :not(a) instead, but since the other text is a direct sibling of the a element you won't be able to target it with a selector.
Instead of using display: none, you can use the visibility property instead:
.list .sub {
visibility: hidden;
}
.list .sub a {
visibility: visible;
}
But note that this will also hide the bullet because it's part of the li element and cannot be targeted separately. If you need the bullet to be shown, you can replace it with a :before pseudo-element, which works slightly differently from an actual list marker:
.list .sub {
list-style: none;
visibility: hidden;
}
.list .sub:before, .list .sub a {
visibility: visible;
}
.list .sub:before {
content: '\2022';
}

Related

Why my list items don't display inline?

i just wrote some lines of code here. I want <span> texts to display below these <h1> but if i edit css <h1> or <span> to " display: block " then the parent element <li> will display as block too.
<ul>
<li><h1>Big Number</h1><span>Description</span></li>
<li><h1>Big Number</h1><span>Description</span></li>
<li><h1>Big Number</h1><span>Description</span></li>
</ul>
This is the style:
ul li {
display: inline;
}
h1 {
display: inline;
}
span {
display: inline;
}
How can I make the <li> display inline and the <span> texts display below <h1> ?
An inline box can't cleanly contain a block box.
Use display: inline-block instead of inline.
Use this way:
ul li {display: inline-block;}
h1 {display: inline-block;}
span {display: block;}
Try this SAMPLE
ul li {
display: inline-block;
}
h1 {
display: inline;
}
span {
display: block;
}
You just have to use the inline-block property on the ul li selector.
ul li { display: inline-block }
jsfiddle.net is not working right now so I can't make an example for you. You're also gonna have to delete the h1 and span style.
An example on CodePen
http://codepen.io/Tudes/pen/dyFDL
The reason why you have to use only the inline-block property on the ul li selector is because h1 is a block element that means it is gonna take the full width of the div and the span will go right underneath it.

How to hover span content from li

I have a simple html code that has some data but the li has image background and on hover i want to show the data from span.
HTML CODE:
<ul class="container">
<li class="icons_27"><span class="data_27">DATA 27 - TORONTO</span></li>
<li class="icons_28"><span class="data_28">DATA 28 - NEW YORK</span></li>
</ul>
CSS:
.container li span {
display: none;
}
.container li span:hover {
display: block;
}
My question is how can i show the span data on hover ?
you need to style the hover on li
.container li:hover span {
display: block;
}
but this will work only if your li is visible even when the inner span has display: none
(otherwise your li have no a visible area in which you can hover).
You may solve this potential issue defining, for example, a width or an height to your list-items.
Or — instead of giving display: none to the inner span — you may use a different style, e.g.
.container li span {
visibility: hidden; /* or also opacity : 0; */
}
.container li:hover span {
visibility: visible; /* or also opacity : 1; */
}
Note: the opacity approach (instead of display or visibility) would also give you the opportunity to make a graceful appearing/disappearing effect using a CSS3 transition
If you want the span to display when the li is hovered, put the :hover selector on the li instead:
.container li span {
display: none;
}
.container li:hover span {
display: block;
}
Demo at http://jsfiddle.net/D3QNr/

Styling specific list within UL

Say this is my setup:
<ul id="filters">
<li>Any distance</li>
<li>10 km</li>
<li>30 km</li>
<li>50 km</li>
</ul>
In my css how can I style my list depending on what UL it is in? I tried this:
#filters ul li {
padding: 10px;
}
But I didn't have any luck, the same with several different variations on this. I know it's a basic question but I'm still learning.
Your selector is incorrect for what you are trying to achieve:
#filters ul li {
padding: 10px;
}
#filters ul li will select li elements that are descendants of a ul that is a descendant of an element with id="filters".
You want:
#filters li {
padding: 10px;
}
You simply want:
#filters li {
padding: 10px;
}
The reason it doesn't work at the moment is because it's saying the ul INSIDE an element with the ID #filters. (e.g. <div id="filters"><ul>...)
Another correct way of styling your list would be ul#filters li. This says that you want a ul element with the ID "filters". This is unnecessary though, since you can only have one element with the ID "filters".
Your selector is wrong.
Below are some alternative selectors that will work just fine:
ul#filters li {
padding: 10px;
}
The above selector will apply to the LI elements of any UL element that has the ID 'filter'. This selector has the highest specificity (in the given context). Here's a good article on specificity http://coding.smashingmagazine.com/2007/07/27/css-specificity-things-you-should-know/
#filters li {
padding: 10px;
}
The above selector will apply to the LI elements of an element that has the ID 'filter'.
#filters * {
padding: 10px;
}
The above selector will apply to ANY element of an element that has an ID 'filter'. I don't advise you to use this, but you could because a UL element has to be followed by LI elements according to the W3C.
The #filters is the ul itself, you must select the children like this:
ul#filters li {
padding: 10px;
}
However, because ID is unique, you can ommit the ul:
#filters li {
padding: 10px;
}
Try this instead:
#filters li {
padding: 10px;
}
It would need to be
ul#filters li{some code}
You put the id or class after the name of the element.
or simply
#filters li{your code}

How can I make my CSS work only if a span is inside an <a> that does not have a class of "folder"?

I have the following HTML:
<ul>
<li>
<span class="toggle"></span>
<a class="folder">
<span>Background</span>
</a>
<ul>
<li>
<a data-href="/C">
<span>History</span>
</a>
</li>
</ul>
</li>
</ul>
I am using the following CSS to make the cursor into a pointer:
ul li span {
cursor: pointer;
}
Is there a way I can modify this so that it does NOT change into a pointer if the <span> is inside an <a> that has a class of folder?
You should be able to use :not() here...
ul li a:not(.folder) span {
cursor: pointer;
}
Since you also have <span> elements occurring inside <li> but outside <a>, you will need to modify the selector a bit...
ul li > span, ul li > a:not(.folder) > span {
cursor: pointer;
}
Alternatively (or if you need to support browsers that don't understand :not()), just override it:
ul li span {
cursor: pointer;
}
ul li a.folder span {
cursor: auto;
}
Just add one more rule after your existing rule:
​ul li a.folder span {
cursor:initial;
}​
JSFiddle
Note that initial is not quite "standard", so you may want to use e.g. default or auto;
Add this CSS also:
ul li a span{
cursor: default;
}
Check it in http://fiddle.jshell.net/5w2SX/
below CSS with work for all browsers
.folder a {
cursor: default !important;
}
ul li a span {
cursor: pointer;
}
ul li a.folder span {
cursor: default;
}
first part will convert cursor on elements "ul li a span" into pointer.
second line defines the exceptions, where all with class folder will have default cursor.

One-level drop-down menu from ul list styled with css possible?

I have a list of items of which only the first is visible and on list hover shows all items with side effect of changing the position of surrounding content. How to evade this unwanted effect?
Here is an example list:
http://jsfiddle.net/dsbonev/z8Sjy/
All examples that I checked for styling menus have a two-level structure (parent -> children). On parent hover children are shown. But I don't have a parent to hover onto nor I want to promote one of the children as a parent by moving it out of the list and thus breaking the semantic of the markup.
Figured it out! This is what I wanted:
http://jsfiddle.net/z8Sjy/
I accept comments with shortcomings or improvements of this method.
HTML
<div class="list-wrapper">
<ul class="items">
<li>stackoverflow</li>
<li>superuser</li>
<li>serverfault</li>
</ul>
</div>
CSS
.list-wrapper, .items {
display: inline-block;
}
.list-wrapper {
position: relative;
background-color: blue;
height: 1em;
}
.items {
position: absolute;
background-color: red;
}
.items > li:not(:first-child) {
display: none;
}
.items:hover > li:not(:first-child) {
display: block;
}
You could position the list absolutely and then add padding to the paragraph to compensate.
http://jsfiddle.net/z8Sjy/2/
Instead of using display: none & display: block use visibility: hidden & visibility: visible. That way they take up the space in the HTML document, but are not shown:
Working example: http://jsfiddle.net/z8Sjy/3/
Edit
The following CSS would be more cross-browser compatable for showing / hiding "not first-child" elements as the selector :not is actually CSS3.
.items > li:first-child ~ li {
display: none;
}
.items:hover > li:first-child ~ li {
display: block;
}