Forum Moderators: not2easy

Message Too Old, No Replies

Are "complex" selectors allowed?

Trying to hide certain content only if another non related id is present

         

kewlniss

5:35 pm on Sep 2, 2004 (gmt 0)

10+ Year Member



Hello all,

/* start of mumblings - feel free to ignore */
While I have read many posts in this forum, I never registered to ask a question until today. So here it goes ... (please keep snickering to a minimum :) )

I have been in the process of converting our eCommerce system from an old HTML font/table/junk layout to one using a more cleaner HTML + CSS layout.
/* end of mumblings */

Anyway, here is my question...

I have a "complex" 3 column layout with a header and footer. In the right column I list the categories of the site. It has a category image with a category name. Both are links. On some pages I want the category image to be displayed along with the category name. On others I just want the category name.

Here is a stripped down version of the HTML


<div id="wrapper">
<div id="header">Header</div>
<div id="main">
<div id="leftcontentwrapper">
<div id="leftcontent">Left Content</div>
</div>
<div id="centercontentwrapper">
<div id="centercontent">Center Content</div>
</div>
</div>
<div id="rightcontentwrapper">
<div id="rightcontent">
<div id="categorylist">
<span class="categoryimage"><a href='#' ><img id="imgCategory" src='someimage.gif' alt='' /></a></span>
<a class="categoryname" href='#'>Shirts</a>
</div>
</div>
</div>
<div id="footer">Footer</div>
</div>

Now I want the .categoryimage from above show up all the time _except_ when the #centercontent contains the id #productdetail.

I am hoping to be able to do something like


...some complex selector... .categoryname { display: none; }

and example of what ...some complex selector... might be


#centercontentwrapper > #centercontent > #productdetail
+
#rightcontentwrapper > #rightcontent > #categorylist .categoryimage { display: none; }

but am not sure if that is possible with the above structure. Or maybe there is a better way to do it. I can do it through server side script and perhaps that is where it should stay, but I have gotten so excited using CSS for displaying the data that I would love to do it this ( or a similar ) way.

In summary the rule is only hide .categoryname if #productdetail is on the page.

Is there a way to do that? (Sorry for being long winded)

Thanks!

Chad

jollymcfats

8:59 pm on Sep 2, 2004 (gmt 0)

10+ Year Member



If you put a "product detail" indicator higher up the div tree, you can hide the image with a simple selector.

For example:


<div id="wrapper" class="productdetail">
<div id="header">Header</div>
<div id="main">
<div id="leftcontentwrapper">
<div id="leftcontent">Left Content</div>
</div>
<div id="centercontentwrapper">
<div id="centercontent">Center Content</div>
</div>
</div>
<div id="rightcontentwrapper">
<div id="rightcontent">
<div id="categorylist">
<span class="categoryimage"><a href='#' ><img id="imgCategory" src='someimage.gif' alt='' /></a></span>
<a class="categoryname" href='#'>Shirts</a>
</div>
</div>
</div>
<div id="footer">Footer</div>
</div>

Then this will hide the image:


#wrapper.productdetail .categoryimage { display: none; }

Marking your outer wrapper with classes like this is a pretty simple and powerful way to control all sorts of css presentation.

drbrain

9:18 pm on Sep 2, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Now I want the .categoryimage from above show up all the time _except_ when the #centercontent contains the id #productdetail.

That can't be done in CSS2. CSS selectors work by moving down the document from the root, and may step sideways with the + selector, but never look back up the tree. You might be able to use the CSS3 :not() selector, but I'm a bit fuzzy on it still, since it isn't yet widely implemented.

IE6 doesn't support the + and > selectors, unfortunately.

Your document structure does seem to be overly complex, and you use a lot of extra ids. Something like this might be simpler:

<body><!-- formerly id="wrapper" -->
<div id="header">Header</div>

<div id="main">
<div id="left">
<div class="content">Left Content</div>
</div>

<div id="center" class="wrapper">
<div class="content">Center Content</div>
</div>
</div>

<div id="right">
<div class="content">
<div id="categorylist">
<span class="categoryimage"><a href='#'><img id="imgCategory" src='someimage.gif' alt='' /></a></span>
<a class="categoryname" href='#'>Shirts</a>
</div>
</div>

</div>

<div id="footer">Footer</div>
</body>

This lets you use selectors like this to style sections of the document:

#right { ... }
#right content { ... }

Unless you absolutely must have a wrapper div for styling purposes, get rid of it.

Additional things you can do is replace div categorylist with a real list. One of my goals of design is to have a sensible looking document with no styles at all. It may be *ugly* but you I still want it to look sensible.

kewlniss

9:52 pm on Sep 2, 2004 (gmt 0)

10+ Year Member



Thanks for the replies so far ...

jollymcfats, unfortunately, I don't have the luxury of putting the productdetail in with the wrapper. It has to be inside of the #centercontent div.

drbrain, I am using a template for all my pages that work in a number of different eCommerce apps each with it's own requirements. The goal is to create one main template that deviates just a little bit but nothing too extreme. With this layout it allows me to have a header, left center (and / or) right columns plus a footer that spans the entire page regardless of which column is the tallest (since all info is dynamic). Also, I am trying not to use any "CSS Hacks" since I don't want to have to update 60+ sites when bug 1 of said browser is fixed, but bug 2 isn't. (The author of quirksmode dot org has compelling reasons why we shouldn't use one bug to fix another). So because of that I have this rather excessive divs ... but it still WAY beats the amount of tables that were there!

Now, I do like the idea of just having a content class instead of each container having it's own id ... I will incorporate that, but I don't think I can get rid of my wrapper, but I could be mistaken. I will definitely look into it deeper.

I appreciate all of your help ... now I _know_ not to try and find a solution for that via CSS. I guess I will just go back to hiding content inside of my server side code.

Thanks again for both of your help!

drbrain

11:05 pm on Sep 2, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



There is another option, positioning.

You may be able to do something like which hinges on you being able to modularly build your HTML:

For an image:

<div class="hasimage">
<image>
<left div>
<center div>
<right div>
<span>
</right div>
</div>

and for no image:

<div>
<left div>
<center div>
<right div>
<span>
</right div>
</div>

Then use this CSS:

.hasimage #right .blahblahblah {
/* make a space for the image */
}

.hasimage img {
/* position image into the space you made */
}

There probably *is* a CSS solution, bet the solution may not be apparent until you gain more experience.

Best of luck!

kewlniss

2:23 am on Sep 3, 2004 (gmt 0)

10+ Year Member



I just finished writing up this real long reply ... and right before I was going to send it I realized a way I can get this to work after all!

I need to thank both of you for your help because jollymcfats talked about moving the productdetail class or id up inside of wrapper. I immediately disregarded it since I didn't think it could be done with my current framework. So I moved on to drbrian who told me that what I was trying to do wouldn't work as is. I thanked him ... and he responded with

There probably *is* a CSS solution, bet the solution may not be apparent until you gain more experience.

which made me think some more ( was so close to going back to my old habits ) ... and bam it hit me ... while I can't add in a class attribute to the wrapper element dynamically ... I CAN put in a "dummy" place holder with very little effort. Now this is probably so specific to my uses that it won't help anyone ... but just in case I am going to explain what I am going to do. Obviously, feel free to ignore (and apolgies up front for wasting storage and bandwidth :)


<div id="wrapper">
.<div id="productdetailpage">
...<div id="header">Header</div>
...<div id="main">
......<div id="left">
.........<div class="content">Left Content</div>
......</div>
......<div id="center">
.........<div class="content">
............<div id="productdetail">Data</div>
.........</div>
......</div>
......<div id="right">
.........<div class="content">
............<div id="categorylist">
...............<span class="categoryimage"><a href='#'><img id="imgCategory" src='someimage.gif' alt='' /></a></span>
...............<a class="categoryname" href='#'>Shirts</a>
............</div>
.........</div>
......</div>
...</div> <!-- end main -->
...<div id="footer">Footer</div>
.</div>
</div>

CSS
#productdetailpage #categorylist { display: none; }

With my template framework, I can't add a class to an existing tag (which would be cleaner) ... but I can create a start tag and an end tag. It isn't pretty in my markup, but it is a much lesser evil than maintaining minor variations of the same markup page when CSS handles that task exceptionally well.

I may be able to reduce some of those div's but the idea is the same.

Thank you both for your time!

kewlniss

4:10 am on Sep 3, 2004 (gmt 0)

10+ Year Member



Above I mention ...

#productdetailpage #categorylist { display: none; }

and that is what I would use to remove the entire category listing on the right.

In my original post I was just talking about removing the category image itself ... that is simply

#productdetailpage .categoryimage { display: none; }

D_Blackwell

4:26 pm on Sep 3, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



IE6 doesn't support the + and > selectors, unfortunately.

Is there a way to force the rendering, as there is with :hover? That would be a powerful tool! Dr. Doc?

drbrain

4:34 pm on Sep 3, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Apparently IE7 does:

[dean.edwards.name...]