Saturday, October 24, 2015

CSS tabbing misadventure

I tried to rewrite this such that I didn't have to have styles for specific tabs and that I could instead have a stylesheet applicable to all tabs. The best I could do was:

<!DOCTYPE html>
<html>
   <head>
      <title>Whatever</title>
      <style type="text/css" media="all">
         body {
            background-color: #DDEEEE;
         }
         #innerWrapper {
            height: 37px;
            width: 190px;
            margin: -37px 0 0 10px;
            border-left: 1px solid #000000;
         }
         #innerWrapper section {
            float: left;
            border-right: 1px solid #000000;
            border-top: 1px solid #000000;
            border-bottom: 1px solid #000000;
            height: 30px;
            padding: 5px 5px 0 5px;
            background-color: #F2F2F2;
         }
         #innerWrapper section article {
            display: none;
         }
         input[type=radio] {
            display: none;
         }
         input[type=radio]:checked + section {
            background-color: #FFFFFF !important;
            border-bottom: 1px solid #FFFFFF !important;
         }
         input[type=radio]:checked + section article {
            display: block !important;
            width: 180px;
            position: absolute;
            left: 40px;
            margin-top: 20px;
         }
         label {
            cursor: pointer;
         }
         #outerWrapper {
            margin: 71px 20px 20px 20px;
            border: 1px solid #000000;
            background-color: #FFFFFF;
            height: 80px;
            width: 200px;
         }
      </style>
   </head>
   <body>
      blood stains, ball gowns, trashin' the hotel room...
      <div id="outerWrapper">
         <div id="innerWrapper">
            <input name="tab" id="foo" type="radio" checked />
            <section>
               <label for="foo">foo</label>
               <article>My friends and I, we've cracked the code.</article>
            </section>
            <input name="tab" id="bar" type="radio" />
            <section>
               <label for="bar">bar</label>
               <article>We count our dollars on the train to the party.</article>
            </section>
            <input name="tab" id="baz" type="radio" />
            <section>
               <label for="baz">baz</label>
               <article>And, everyone who knows us knows that we're fine with this.
                     </article>
            </section>
            <input name="tab" id="qux" type="radio" />
            <section>
               <label for="qux">qux</label>
               <article>We didn't come from money.</article>
            </section>
         </div>
      </div>
      ...jet planes, islands, tigers on a gold leash
   </body>
</html>

 
 

There are a couple things that are bad about this. First of all, the absolute positioning unfortunately brings with it an inability for the content to push the bottom of the content box downwards on the page. The content thus can only be as tall as I've set the faked content box to be or it will run beyond it. Honestly, this isn't the end of the world as one could just slap a vertical scrollbar on the content if need be. However, the use of "left" is really, really bad. This isn't going to work well in modern web sites wherein all of the content sits inside of a centered div. One could, I suppose, put all of this stuff inside of an iFrame and then summon it into a centered page but if you are going to the lengths of undertaking such a hack you might as well just call out the tabs by id in CSS, you know? If you don't know how many tabs there will be and thus find yourself struggling to write some CSS for it you could make the CSS bubble up inside of style tag inside of the rendered HTML. That way the styles could be calculated on the server side and bubble up to the markup the same way the number of tabs might. You'd number the ids as tab01, tab02, etc. in this paradigm. Anyways, my flawed mess above looks like so:

 
 

Addendum 10/25/2015: I slept on it and realized that one could approach the "left" problem like so:

left: calc(50% - 13px);

 
 

The fifty definitely needs to be a fifty in the name of centering off the center edge but the thirteen should be replaced with whatever number suits your purposes for positioning. You probably would need an offset. I checked and this worked in three of the four browsers shown above. The outlier was the Safari browser (for PC) which hasn't been updated since 2012.

No comments:

Post a Comment