September 23rd, 2011
3:17 pm
Preventing Overflow with long strings in table cells

Posted under JSF
Tags , , , , , , ,

I hit this issue when displaying email addresses in a p:dataTable.

The problem is that for long strings without spaces, the browser tries to enlarge the table cell width, causing the table to stretch beyond the correct bounds and messing up the layout. A column will wrap and enlarge vertically, but this will only be done when it can break on a space. Setting the widths for the columns is technically just advisory on the browser and may be overriden if needed.

There are various solutions to this, and this post here in Stack Overflow discusses them.

My chosen solution in this case was the following:-

  • Place the text in the cells in <spans>, to allow them to be styled with CSS. You could also style the column <td> cells by applying style/styleClass attributes to the p:column tag, but this will limit your flexibility – for example if you do this p:column does not expose the title attribute on the <td> (see below)
  • Style the <spans>  with display:inline-block;overflow:hidden. This allows a width to be set for the span (I used the same width as set for the column), and hides any overflow (which would otherwise bleed into the next column).
  • Text will still wrap on spaces if they are present, but long strings without spaces, such as email addresses or file paths, do not cause a problem, but they will truncate and so will not be fully visible by default.
  • I include a title attribute on the span to include the full text. This allows the full text to be displayed on hover for any long strings that are truncated in the cell.

This neatly solves the problem, and prevents the table layout messing up.

No Comments »

July 26th, 2011
10:31 am
Extra unwanted margin around an HTML textarea in Google Chrome

Posted under CSS
Tags , , , , , ,

Chrome places an unwanted 4px bottom margin on a textarea, which is impossible to elminate purely by the margin settings.

In addition, the other browsers sometimes have related issues.

This post on StackOverflow discusses the issue, and the Chrome bug issue may be found here.

Issues like this can be caused in inline and inline-block elements, due to side effects of the line height/vertical alignment of textual elements. They can be hard issues to diagnose as the cause of the extra margin is not readily visible in tools like Firebug or Chrome’s developer tools/debugger. In order to see it, I added an extra div with a border around the element, and the margin was then clearly visible, but of course it was still not reported as a margin on the textarea element, which steadfastly maintained its story that no margin was present!

As per the StackOverflow article, there are 2 ways around this issue:-

  • If the textarea is set to have vertical-align:top then this eliminates the problem. It also has the advantage of maintaining the element as inline-block – in Chrome’s case this is the default, and with other browsers this will often be used in order to allow margins etc. which an inline element will not allow.
  • Another fix for the problem is to set the textarea to display:block, i.e. to make it a block element. This is fine, but it should be noted that as the element is not natively a block type element, IE7 and earlier IE versions will not handle this. IE8 and IE9 will allow an inline element to be redesignated as a block one. Therefore, the first method has better browser compatibility.

No Comments »

July 21st, 2011
10:58 am
More useful Posts about inline-block and alignment

Posted under CSS
Tags , , , , ,

Update 18/1/2012

I was having trouble getting cross theme and cross browser consistency in aligning text adjacent to an icon in a series of IconTextButtons of mine, inside a toolbar.

Both the icon and the text were in spans set to display:inline-block and the spans were inside a div. I found the following useful in solving the issue :-

  1. The key issue turned out to be that the line-height was very different across Primefaces themes. The font size was constant at about (effectively) 11.5px, but the effective line-height varied with the them between 12px and 16px. This was the main cause of the issue in getting good alignment.
  2. I just set a fixed line-height of 14px for all the buttons in the toolbar, and this solved the cross theme (and cross browser) issues.
  3. The text was to the right of the icon, and found that tweaking the top margin for the icon set the position of both it and the text vertically, due to the adjacency-relative way in which vertical-align works.
  4. In order to adjust the vertical alignment of the text slightly relative to the icon, I found that setting a small bottom margin on the text achieved this, so one to bear in mind when experimenting.
  5. I had also tried padding changes as well as margin, but the effects (or lack of them) were similar to tweaking the margins.

 

Original Post

This post gives a good description of the effect on margins and padding for inline vs. block elements elements.

This StackOverflow post point out the effect of adjacent inline elements on the vertical alignment of an element – in this case an element was pushed down a few pixels due to the prescence of adjacent inline elements.

I was trying to align text and buttons in a narrow vertical toolbar, and as I have found previously, different browsers render differently.

The best consistency across browsers was obtained as follows :-

  1. Use display:inline-block to allow vertical margins to be obeyed on the elements. They can then be precisely adjusted (but may still behave differently depending on the adjacent elements). inline-block has decent cross browser support. IE6 and IE7 only support it on elements with a native type of ‘inline’ – see this post for cross browser support details.
  2. Using vertical-align:bottom seems to give the best cross browser consistency.
  3. Top and/or bottom margins generally need to be tweaked for each individual case depending on element adjacency. (Depending on the case you may need to set a top or a bottom margin to have the desired effect consistently across browsers.) For example, I had to treat a text only span differently to a text span adjacent to a couple of buttons on the bar.

No Comments »

November 23rd, 2010
11:38 am
Using floats to place a border around a control group/toolbar

Posted under CSS
Tags , , , , , , ,

I originally used display:inline-block, line-height and vertical-align:middle to do this as detailed here, but the results were inconsistent across browsers.

Using floats is a much better solution for a number of reasons – details are as follows:- 

  • The controls are floated left inside a div which is itself floated left. As the div is floating, it auto resizes to fit around the content, and so scales to fit unknown control sizes.
  • The controls are all set to have fixed top and bottom margins (4px in the example), and the leftmost and rightmost also have similar left and right margins respectively.
  • The floated div is set to have the desired border and background etc. – in my case, I use Primefaces/jQuery UI theme style classes to apply theme look and feel.
  • The floated div is then placed inside another outer div, which may be of fixed dimensions. This allows the control group to adjust in size, but to be located inside a fixed area on a page.
  • If the outer div is of fixed size and non floating, the floating inside it is invisible to the rest of the document, so it is not necessary for example to clear the float.
  • If desired, the outer div can be set to overflow:auto to allow scroll bars if the size of the inner floating div exceeds the space allocated for it on the page.
  • If the area surrounding the control group is also floating, the outer div can also be set to float with no size specified, so the concept works well in both floating and fixed size situations.
  • display:inline-block and vertical-align:middle are not used with this method.

 This mechanism has the following characteristics:-

  • The control group bordering works nicely and consistently with the Primefaces/jQuery theme styling, as rather than trying to centre the controls in a fixed border, instead we vary the border size and keep the margin between the controls and the border constant.
  • The approach makes use of the laws of Gestalt Psychology – the eye notices even small imperfections in the alignment of the controls and their relationship to the border because they are close and obviously grouped/related.
  • Conversely the position of the entire bordered control group within its surroundings (the outer div) will typically not be so critical – it will likely be in a larger area of white space between it and adjacent items,  and so its position and size within that space matters less than the control / border relationship.

A caveat to all this is that it is still not perfect – the simple example below does not perform quite as well in terms of cross browser alignment as the Primefaces/jQuery UI version, as the Primefaces themes apply their own styling as well which changes the situation. This could of course be improved by adjusting the margins individually for different controls in the group to get the best overall cross browser alignment. One very important goal I am trying to acheive is to avoid browser specific CSS. The Primefaces/jQuery UI CSS does in general have browser specific tweaks which will help it in certain situations.

Overall though this approach performs significantly better than the previous method using vertical-align:middle etc. and has the advantage of being fully floating/dynamically sizing if required. An example of this approach follows :-

<!DOCTYPE html>
<html>
<head>
 <style type=”text/css”>
  .ss-outerdiv {
   height: 40px;
   width: 200px;
   background-color: orange;
  } 
  .ss-controlgroup {
   float: left;
   background-color: green;
   border: 1px solid black;
  }
  .ss-select, .ss-leftbutton, .ss-rightbutton {
   margin-top: 4px;
   margin-bottom: 4px;
   float: left;
  }
  .ss-select {
   width: 120px;
     font-family: Arial,Verdana,sans-serif;
     font-size: 11px;    
   margin-left: 4px;
   margin-right: 4px;
  }
  .ss-leftbutton, .ss-rightbutton {
   height: 20px;
   width: 30px;
  }
  .ss-leftbutton  {margin-right: 2px;}
  .ss-rightbutton {margin-right: 4px;}
 </style>
</head>
<body>
<div class=”ss-outerdiv”>
 <div class=”ss-controlgroup”>
  <select class=”ss-select”>
  <option value=”Test”>Test Value</option>
  </select>
  <button class=”ss-leftbutton ss-button”></button>
  <button class=”ss-rightbutton ss-button”></button>
 </div>
</div>
</body>
</html>

No Comments »

September 18th, 2010
11:08 am
Using display:inline-block and vertical-align in CSS

Posted under CSS
Tags , , , , , ,

Update 23/11/2010

Having experimented with this extensively on different browsers, I have found inconsistent results across browsers when trying to vertically centre a group of controls in a bordered div which closely surrounds them. If you need just a few pixels between the controls and the border, vertical centering does not work in a consistent browser independent manner. For larger centring, e.g. for centring a paragraph of text in a large div, the differences may not be noticeable, but at small scale they definitely are. For placing a close border around a group of related controls, my preferred method is now to use floats as detailed here. Note that the fact that floats are used does not force the rest of the document to use floats or to have non fixed sizing – the floats can be invisible to the outside due to a second outer non floated fixed size div. Also, the floated version works better when the contained controls are of variable or unknown size.

Original post

I originally used this here in order to centre the text on a Primefaces button, the usage of inline-block was incorrect.

What it does not do is allow you for example to centre a <span> element vertically and/or horizontally in a parent div!

What it does do is to allow setting of the alignment of an inline element relative to adjacent inline elements on a line (not relative to the parent container). It will therefore work within a <td> but not within a <div>

There appear to be a lot of fuzzy and partly incorrect articles on the net about this, and it was hard to find clear definitions. even the W3schools site does not greatly help, and does not appear to list for each element whether it is an inline or block element by default, which seems quite an omission.

In the end I found some helpful posts on it here and here which cleared it up for me, and explained why my simple example of a <span> in a <div> would not centre vertically with inline-block and vertical-align:middle!

Note regarding the use of vertical-align, a typical gotcha on this is if you have a horizontal group of buttons/combos and attempt to use top/bottom margins to try to centre them vertically, you may wonder why you do not get the expected behaviour as the margins do not appear to be properly honoured. This is a classic case for using display:inline-block and vertical-align:middle on all the controls.
Primefaces note:- the Primefaces commandButton components are set to  display:inline-block by Primefaces, using the internal jQuery ui-button class.

No Comments »

June 9th, 2010
5:06 pm
Centre text and other items e.g. on a Primefaces command button

Posted under HTML
Tags , , , , ,

Update

This post originally used display:inline-block and vertical-align:middle thinking mistakenly that these were part of the fix for the problem.
See here for a more complete understanding of it.
The modified CSS below works fine just by removing the padding and setting the font.

Taking the Primefaces commandButton as an example, the label is embedded in a span:-

<button attr1=value attr2=value…>
<span>Submit</span
</button>

The button has many attributes which are not relevant to this discussion.
However, as the span is an inline element, it does not have a top/bottom margin, width or height and using text-align:center; in css has no effect.

The default Primefaces button has fixed padding for the label, which works fine by default but which is a pain when you change the size of either the button or the text.

The following rules remove the padding and set the desired font correctly to centre the text for the Primefaces commnadButton:-

.ss-textbutton {
height:20px;
width:52px;
}
.ss-textbutton > .ui-button-text {
font-size:90%;
font-weight: bold;
padding:0px;
}

This CSS is activated when the class ss-textbutton is passed to the styleClass attribute of the commandButton tag.
This example declares a 52 x 20 button. It then targets the <span> within the button using ss-textbutton > ui-button-text, as the <span> in the commandButton has the ui-button-text class. It does the following to the <span>:-

  • sets a font size and weight
  • removes all the padding, so that the centring works correctly

In this example, I have deliberately not changed all buttons globally. The Primefaces documentation explains how to use the classes  ui-button, ui-button-text and ui-button-text-only to skin all buttons globally if this is desired.

This now allows us to resize our button, change the font size and the text, and still have the label nicely centred. We don’t have to mess around with tweaking the padding and other attributes in every case, which is a whole lot simpler and more modular.

No Comments »