Forum Moderators: not2easy
/* 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
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.
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.
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!
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!
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!
#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; }
[dean.edwards.name...]