Does LESS have a parent selector? - css

General structure of my LESS is like:
div {
table { .. }
}
div {
table & { .. }
}
Wanting to know the CSS-only solution using LESS here. I have:
<div>
<table></table>
</div>
And I want to do something like:
div {
& > table:empty { display: none; }
}
But completely opposite of what this is doing and instead of affecting the table here, it affects the div. Of course this is just an example since this is saying hide table if empty whereas I want to say hide div if child table is empty. I want a LESS version that will hide the div. Due to padding and a border the div is visible even when the child table is empty.
Thinking about it I think the answer will be no because LESS compiles to actual CSS and since there is no way to accomplish this in CSS, I'm assuming there's no way in LESS either. It just doesn't hurt to ask.

You're right - there is no parent selector in CSS, and therefore LESS - meaning, you can't style an element's parent based on a selector for the element itself. I would look for a solution using whatever script framework or backend framework you have that's building your markup.

Related

Is it proper syntax to "nest" id declarations inside other id declarations in CSS?

So, I'm not sure what I've stumbled upon here. I'm working with some CSS and I know it is common place to do something like this:
#content{
/* Style the content div. */
}
#content p{
/* Style all p elements in the content div. */
}
I'd like to give one specific p element a float:right style. Only one such p element will occur in the content element. Naturally, I'd just give this element an id, but then I had the idea to do it this way:
#content #right_floating_p{
float:right;
}
This works when I run the code, but I was wondering about best practice and whether or not this actually does anything scope wise. I could just as easily define a separate id for right_floating_p, but to me it feels natural that it should be defined with the content id because it will be used only on one p element inside the content element.
If anyone has any information about this syntax, please let me know. Thanks!
My recommendation is to only include the last ID. This is fairly standard separation of concerns. What if you want to change the first ID #content, but the last one #right_floating_p still makes sense and shouldn't change? There is more room for error if you specify something unnecessarily.
Other reasons this is good:
Smaller, faster (but barely) download size for your users.
More readable, in my opinion.
Faster (but barely) performance.
Over-qualifying tags is bad practice in general, as far as performance goes. Browsers read your selectors from right-to-left, by the time it interprets your #content selector, that information is pointless. My advice is to not trust that the browser will optimize for this.
Alvaro nailed it in his comment above.
The id must be unique on the page, but not necessarily across the whole site. So, for instance, if you had the #right_floating_p element on every page, but it had a #content element as an ancestor only on a certain page where you wanted it styled differently, then you'd want to use the #content #right_floating_p selector to apply the context-specific style.
I would suggest only using the most precise selector as you can, not only for readability and file size, but also for specificity.
CSS selectors have a specificity to them, so if you were to override it later (such as with a media query), the more specific selector will override the less specific one.
#content #right_floating_p {
color: red;
}
div #right_floating_p {
color: green; /* Will not apply, as it's less specific */
}
p {
color: black; /* Even less specific */
}
It will work having the first selector, but it's not necessary.

CSS nesting properties... At least I hope that's what it's called

I was wondering if there was a way to use css to style a wrapper a certain way ONLY if it had a div with a specific id inside. Let's say that I have
<div class="intro_wrapper"></div>
in several places throughout the site but want to change the padding ONLY if it
<div class="intro_wrapper">
<div id="slider"></div>
</div>
has #slider inside of it. The thing is that I want to make it have less padding when #slider is nested in it so I can't really mess with the margin for #slider without cutting off the content all weird. I tried using negative margins but it ends up cutting off the image I have in a weird way.
I know you can use stuff like p + p for paragraphs that have paragraphs following them, so I am assuming there may be a way to do something like I am trying to. Thanks in advance.
You cannot do that with any CSS rules at this point as a reverse combinator to apply style on parent based on child. Instead you can hack it by adding a margin to the child instead.
div.intro_wrapper > #slider
{
margin:20px;
}
Whilst I think PSL's answer is already pretty good (cross browser, simple etc.) it doesn't help if you actually need to use a parent selector. Whilst at the moment it's best to avoid this when you can, there are definitely some circumstances which may require a parent selector (or some such alternative).
One solution if you absolutely have to use a parent selector would be jquery, its selector engine recongnises the :parent selector, for example you could do:
$("#slider:parent").addClass('padded_intro_wrapper');
Then in your CSS:
.padded_intro_wrapper
{
padding: 20px;
}
Equally, if the #slider div isn't always inside the .intro_wrapper div you could do:
$('#slider').closest('.intro_wrapper').addClass('padded_intro_wrapper');
That's where it starts getting a bit messy though.
EDIT: Fiddle if you're feeling lazy

CSS show element attribute value, not element content

I have elements with this pattern (XML, not HTML, but CSS should still work):
<expan abbr="XX">YY</expan>
Sometimes I want to see "YY" in the output, sometimes I want to see "XX". No problem when I want to see "YY" and not the attribute value: just leave it as is. No problem if I want to see BOTH the element content and the attribute value: this bit of CSS does that:
expan:after {content:attr(abbr);}
will display <expan abbr="XX">YY</expan> as "YYXX".
But: problem if I want to see the attribute value and NOT the element content -- that is, if I want to see just "XX". I can use either CSS display or visibility to hide the element <expan>. But it hides EVERYTHING, including the :after pseudo-element. So, this code:
expan:after {content:attr(abbr);}
expan {display:none;}
Shows nothing at all.
So, good folk... help. This seems a very obvious thing to want to do. Of course, I could do it pretty easily manipulating the DOM with Javascript. But for various reasons, I don't have that option. I'd like to do it with simple CSS. Can I??
You'll have to use some kind of hack where the element is still there but only the pseudo element (:after) is visible to the user. An example of this would be color. If you know it's only text, then you can set the color to transparent on the main element, and set it to a real color on the pseudo. You'll still have a blank space to deal with, but you can fix that with position: relative on the parent and position: absolute on the pseudo element, because the pseudo element is a child of the main element. note that the text is still there, but you only see it if you highlight it with the mouse. That's fixable too, with ::selection, but it would still be copyable by accident, and ::select is only available in modern browsers.
Here is a demo showing what I mean: DEMO
EDIT: This one should work with text around it, but you'll have to increase the width in order to add more text: DEMO
Works for me in Chrome and Firefox.
One partial solution is to set the expan font-size to 0 and the :before content font-size to the desired size:
expan:before {
content: attr(name);
font-size: 15px;
}
expan {
font-size: 0;
}
Trying to set the :before font-size to 100% did not work.
You can only set the 'content:' attribute on ::before and ::after psuedo-elements.
But what you can do is just provide both your texts in two separate attributes, like this:
<div long-text="This is very long text" short-text="Short text">
<!-- this part is empty -->
</div>
Then your CSS can switch between them like this:
.AltText::before { content:attr(long-text); }
#media screen and (max-width:1200px) {
#HeaderTabContainer .AltText::before { content:attr(short-text); }
}
Or you could use a third attribute to toggle between them.

CSS Selecting element after chosen class

I'm modifying JQuery UI Accordion Menu, which currently has a structure as below:
<h3>Title</h3>
<div>Children</div>
<h3 class="no-children">Title</h3>
<div>Children</div>
<h3>Title</h3>
<div>Children</div> ...
As you can see, the middle title has no children, so what I want to do in CSS is something along the lines of selecting the div that occurs after the .no-children class and hide it. These are not nested so I can't do this the easy way.
I know I can display:none but I can't seem to select the correct element.
Is there a way to do this?
.nochildren+div{
/* Style goes here */
}
This selects a DIV that that is immediately preceded by a element with the the .nochildren class. This will only work if both elements are on the same level, many older browsers will have issues with it.
http://www.quirksmode.org/css/contents.html
If you are using jQuery there is an easy way of doing this Here
You could use
$('.no-children').next().hide();
or .nextUntil();
http://jsfiddle.net/lollero/DqpPd/1/
CSS way would be
.no-children + div { display: none; }
http://jsfiddle.net/lollero/DqpPd/ ( ie7+ )

Class declaration Header - HTML 5

I was trying to put a image (logo) in the header element provided by HTML5 and I am curious if anyone knows if it is possible to declare a class in CSS something on the lines of header.image?
I tried header.image and it didn't seem to work, however as soon as I had the class named just .headerimage then it seem to be picking up the padding property I was trying to apply.
I'm doing some very basic learning as it's been sometime I picked up HTML code. Please help if your time permits. Thanks
I was trying to put a image (logo) in the header element provided by HTML5 and I am curious if anyone knows if it is possible to declare a class in CSS something on the lines of header.image?
I tried header.image and it didn't seem to work, however as soon as I had the class named just .headerimage then it seem to be picking up the padding property I was trying to apply.
I'm doing some very basic learning as it's been sometime I picked up HTML code. Please help if your time permits. Thanks
This is not the entire HTML/CSScode, but I could manage to take some screenshots. You guys helped me answer some questions and understand how period is not relevant to what I was trying to do.
Screenshot 1: https://skitch.com/android86/fm4r7/dreamweaver ( HTML design view) Screenshot 2: https://skitch.com/android86/fm4fd/dreamweaver ( CSS)
In the screenshot 1, I tried to have the links for website Contact and Login as a part of the Nav tag provided by html 5, however I wanted these to be horizontally next to the hgroup. I assigned a width to hgroup and now I have a lot of space to the right of hgroup however the nav is starting to line up horizontally, is this something I should handle with position or float property in CSS? I tried both in various combinations, I assigned a width to nav in order to fit in the area however it doesn't seems to be working. Any clue? The CSS code is in screenshot 2. After looking at the discussion here I thought using class might not be required instead rather parent child relation might be most relevant. I personally thought and read that one should use id's in CSS when it is a very unique scenario and class when we expect to use a certain thing very commonly, is this parent child relation a way of declaring a class? Thanks everyone.
In CSS, a period without spaces like this.thing means:
select elements that have the class thing but only if they are of type this
Period (.) is a special character in CSS, so you can't name classes with periods. Try an _ or a -.
Actually you can't use period in class names, because it is a class selector. For example, is you have a class "foo" applied to some html element, you can style this element in css linking to it as ".foo".
Example HTML:
<header class="foo">
<img class="bar" src="some/path/here">
Some content here
</header>
Example CSS:
.foo { color: #AAA; }
or
header.foo { color: #AAA; }
In first CSS example the style will be applyed to all elements, wich have class "foo". In the second - to all elements, wich have class "foo" and same time are of "header" type.
Returning to your case, I think the only aim is to apply style to image inside of header element. It can be done different ways:
Use the image class
.bar { width: 100px; }
or more concretely
img.bar { width: 100px; }
Use parent-child relations
header img { width: 100px; }
above will apply styles wich lay inside the header element or in its
children elements
header>img { width: 100px; }
this will be ok only for the direct child of header.
Combine two approaches.
If you know for shure that there will be only one image in header element, I can recommend the approach with ">". Read more about different css selectors, ids and classes. It will do the job.
Assuming your markup looks like this:
<header><img /></header>
The selector you want would be this:
header img {...}
If you really did class your image with class="image" (kinda redundant), then you'd want:
header .image {...} /* note space */
This assumes that the browser supports the html header element. If it doesn't, you'd want to use something like html5shim 1 or modernizer 2

Resources