Showing posts with label CSS. Show all posts
Showing posts with label CSS. Show all posts

Refactoring a menu: remove inline CSS

If you’re new to this series, read the “Refactoring a simple menu” and “Changing the background images” first.

The next step in HTML/CSS refactoring was to clean up the very ugly HTML code … I don’t know what I was thinking at that time; the menu full of repetitive inline CSS is plainly stupid.

Looking at the HTML code, it’s obvious that:

  • The row buttons are independent DIV elements;
  • Each row button has a P child and potentially a DIV child (holding the pull-down menu box).
  • The pull-down menu box has P children that are styled identically to the P elements in the row buttons.

So here’s a very obvious CSS solution:

  • Mark the row button DIV elements with a class (rowMenu).
  • Define styling for P, A and DIV children of the DIV.rowMenu elements.

The resulting CSS is pretty simple …

DIV.rowMenu { float: left; position: relative; z-index: 100; }
DIV.rowMenu DIV { position: absolute; display: none; }
DIV.rowMenu P { … original btx170 definition … }
DIV.rowMenu P.down { … btx170_down definition … }
DIV.rowMenu A { color: #000; text-decoration: none; }

… and so is the cleaned-up HTML code:

<div class="rowMenu" id="IDAHYJQB">
  <p><a href="/climbing/myClimbs/myClimbs.asp">First page</a></p>
</div>
<div class="rowMenu" id="IDAKYJQB">
  <script>menuRegister('IDAKYJQB')</script>
  <p id="IDAKYJQB_main"><a href="javascript:menuClick('IDAKYJQB')">Add ...</a></p>
  <div id="IDAKYJQB_sub">
    <p><a onclick="menuSelect('IDAKYJQB')" 
        href="/climbing/myClimbs/myClimbs_add.asp">New entry </a></p>
    <p><a onclick="menuSelect('IDAKYJQB')" 
        href="/climbing/myClimbs/myClimbs_editWall.asp?a=add">Edit</a></p>
    … more …
  </div>
</div>

Next task: get rid of superfluous element IDs.

Refactoring a menu: Changing the background images to borders

Before reading this: read the “refactoring a simple menu” post to get the background information.

One of the stupidities I did in the original menu implementation was to use CSS background images for simple buttons that could be implemented equally well with CSS borders. It would be hard(er) to get rid of background images if I would have had rounded corners or shaded button background, but I had none of those. So here’s the new CSS definition, replacing images with borders.

The new CSS has another great side-effect: the button sizes are specified in EMs, not in pixels, so the buttons get resized automatically if you change points-to-pixels ratio.

.btx170,.btx170_down {
  overflow: hidden; cursor: pointer;
  padding: 0 0 2px 0; margin: 0 0; text-align: center;
  font-family: Verdana, Arial, Helvetica, sans-serif; 
  font-weight: 700; font-size: 8pt; }
  
.btx170, .btx170_down { width: 16em; }
.btx170 { background-color: #FFCE63; border: 2px outset #FFCE63; }
.btx170_down, { background-color: rgb(255,156,0); 
  border: 2px inset rgb(255,156,0); }

Next task: Remove inline CSS

Refactoring a simple menu

Years ago I had to implement a drop-down menu. Nothing fancy; no open-on-hover magic, but a simple line of buttons with drop-down boxes that would open on clicking the button.

There were just a few annoying details: clicking a top-row button should obviously open a drop-down box, but also change state the button’s state to “depressed” and close any other open drop-down box (and change the state of corresponding buttons).

Here is my five-year-old HTML code …

<div style="float: left; position: relative; z-index: 100;" id="IDAHYJQB">
  <p class="btn170">
    <a href="/climbing/myClimbs/myClimbs.asp">First page</a>
  </p>
</div>
<div style="float: left; position: relative; z-index: 100;" id="IDAKYJQB">
  <script>menuRegister('IDAKYJQB')</script>
  <p class="btn170" id="IDAKYJQB_main">
    <a href="javascript:menuClick('IDAKYJQB')">Add ...</a>
  </p>
  <div style="position: absolute; display: none;" id="IDAKYJQB_sub">
    <p class="btn170">
      <a onclick="menuSelect('IDAKYJQB')" 
        href="/climbing/myClimbs/myClimbs_add.asp">New entry </a>
    </p>
    <p class="btn170">
      <a onclick="menuSelect('IDAKYJQB')" 
        href="/climbing/myClimbs/myClimbs_editWall.asp?a=add">Edit</a>
    </p>
    … more …
  </div>
</div>

… the corresponding CSS …

.btn170, .btn170_down { background-repeat: no-repeat; 
    width: 170px; height: 20px; line-height: 18px; overflow: hidden; 
    padding: 0 0; margin: 0 0; text-align: center;
    font-family: Verdana, Arial, Helvetica, sans-serif; 
    font-weight: 700; font-size: 11px; }

.btn170
  { background-image: url('images/button_170.gif');  }   
.btn170_down
  { background-image: url('images/button_down_170.gif'); }

… and JavaScript code …

var topMenuItems = [] ;

function addClass(id,sfx) {
  var se = getElement(id) ;
  if (se.className.indexOf(sfx) < 0) se.className = se.className + sfx ;
}
function removeClass(id,sfx) {
  var se = getElement(id) ;
  var i = se.className.indexOf(sfx) ;
  if (i > 0) se.className = se.className.substr(0,i) ;
}

function menuShow(id) {
  var se = getElement(id) ; se.menuActive = true ; 
  showElement(id + "_sub") ; addClass(id+"_main","_down"); }

function menuHide(id) { 
  var se = getElement(id) ; se.menuActive = false ; 
  hideElement(id + "_sub") ; removeClass(id+"_main","_down"); }

function menuGo(id,l) { menuHide(id); location.href = l; }
function menuSelect(id) { menuHide(id) ; }

function menuClick(id) {
  var i,se ;
  se = getElement(id) ;
  if (se.menuActive) {
    menuHide(id) ; return ;
  }
  for (i = 0 ; i < topMenuItems.length ; i++) {
    if (topMenuItems[i] != id) menuHide(topMenuItems[i]);
  }
  menuShow(id) ;
}

function menuRegister(id) { 
  topMenuItems[topMenuItems.length] = id ;
}

I will not try to explain what this code does, as it’s way too painful. As I’ll walk through the refactoring process, I’ll show you the changes I’ve made and the stupidities in the original code.

Fix Your Web Site Performance Problems (InformIT article)

If you've realized that you might have HTTP-related performance problems when reading my Why is my web site so slow article published by InformIT, you can find a variety of quick fixes and more permanent solutions in my Fix Your Web Site Performance Problems article (also published by InformIT).

Drawing charts in your web pages

Here are a few links that will help you draw great charts in your web pages:

Floating misteries

I guess all would be well if we would just take enough time and read through the CSS standards (at least through the sections documenting the box model and layouts). As that will probably never happen, floats remain a black magic to a lot of people (myself included sometimes). The Make Your Site BulletProof With Floats article published by Peachpit.com could make things a bit clearer … or at least you'll find a few good working examples.

Use JavaScript Progressive Enhancement to simplify HTML table formatting

In the Enrich Your HTML Tables with JavaScript Progressive Enhancement article I wrote for InformIT.com, I'm describing how you can use JavaScript progressive enhancement techniques to add last touches to your HTML table format after the web page has been loaded into the web browser ... and, no, I'm not talking about page layout with tables :), I'm talking about formatting data that deserve tabular format.

How to avoid common CSS mistakes

I admit it - I was also one of those web developers that jumped in CSS waters with helping hand of uncle Google instead of a good introductory and reference book on the topic. If you want to avoid some of the stupidities I've been doing, read the Seven Common CSS Mistakes and How to Avoid Them article I wrote for InformIT.

Centering CSS-based layouts, Detecting text resize and more

The latest collection of links by Meryl Evans contains real gems:

Detecting cached CSS style sheets

Have you ever deployed an improved version of your web pages, just to find out that the visitors have to press Ctrl-R (Reload) to get them right as their browsers have cached the Cascaded Style Sheet (.css) files used in your web site. Renaming the style sheet files every time you change them definitely solves the problem, but requires changing all the related web pages as well.
It's infinitely better if you can detect that the style sheets are cached by the browser (and thus obsolete) and respond with a forced reload. In the simplest case (more about version control in another post), you can detect that the style sheets referenced by your web page are missing a class (or id) selector that you need. Include the browser-independent stylesheet library in your web page and add the following code somewhere in the body of the page:
<script>if (xHasStyleSheets() && ! xHasStyleSelector('.myClass')) location.reload(true);</script>
If you're looking for an ID selector,  replace '.myClass' with '#myID'.