Blog Archives

November 16th, 2010
2:59 pm
JSF 2.0 Composite Components

Posted under JSF
Tags , , , , , ,

This post highlights a few lessons learned whilst experimenting with a simple composite component, in this case an experimental  Primefaces theme switcher component. The component does the following:-

  • Automatically iterates the themes directory on the server to build a list of available themes which are presented for the user to select
  • Generates a simple theme control panel with a border, consisting of a drop down combo listing the themes, with previous theme/next theme buttons to the right.
  • Also allows theme switching via ctrl/shift/left arrow and ctrl/shift/right arrow, to give a quick way of cycling through the themes when choosing one.
  • The component is used on the JSF page in two modes – the first usage is with outputStyle=”true”, themeBase and defaultTheme attributes. It is placed in the <head> section, and it defines the base path for all the theme directories, and the default starting theme (which may be programmatically overriden by setting the theme property in its backing bean, themeSwitcherBean). This mode also outputs the link directive to link the current theme stylesheet to the page. It does not result in the display of the control panel.
  • The second mode is used inside a <form> on the page, and results in the theme switcher panel being displayed.
  • A theme switch results in a form submission, so this must be acceptable to the form logic. If not, i.e. if the form is dirty, the theme switcher must be disabled. This would be done by passing a disable flag attribute to the component, which maps to a disable property of the backing bean, which results in enabling/disabling the controls. At present, a disable feature is not supported.

 

The following salient points were picked up along the way:-

  • The component does not have to be placed in a form. The examples in the Core JavaServer Faces book seemed to always show the client page with the control placed on a form, and also with <form></form> tags present in the custom component implementation. There is absolutely no requirement for the custom component implementation definition to be in its own form.
  • With JSF 2.0, it is easy to pass a value e.g. from a composite component attribute in a call, direct to a backing bean property, as JSF 2.0 now supports method expressions with parameters in EL expressions – just add the brackets and the call arguments. This used to be tricky, and many posts on technical blogs just seemed to answer ‘why on earth do you want to’. Well, perhaps it is unusual, but in this example it feels just the right thing. Normally when linking to a style sheet, one would put the path to the sheet directly on the page in the <link> tag, as one also would when referring to other resources such as images. I have therefore done exactly the same with the themeswitcher – you pass the theme base web context path (along with the default theme name) to the component just as you would do to a <link> tag. This then allows the backing bean to discover the physical theme directory location on disk and automatically iterate it to generate a list of the available themes which are present, which is then passed to the select list of the combo. Whilst the theme base context path could be set up as an injected property of the backing bean, it just does not feel right to do it that way, as normally this knowledge is encapsulated on the page. Sometimes, passing values from the page to a bean is actually the right thing to do!
  • When using an EL method expression to write to a bean property, note that you can just call a setter on the bean directly as if it was a method, giving the “set” prefix, and passing the value as an argument. You literally just plant the EL call on its own in the middle of the page. (You can of course also use another custom method if you wish, for example if you want to pass a number of properties in a single call). Furthermore, when calling for example a setter or any other method that returns void, nothing is written to the page, as you would expect. In the example code below, the EL expression #{cc.attrs.bean.setThemeBase(cc.attrs.themeBase)} does exactly this.
  • A composite component acts as a JSF naming container. Naming containers are required to ensure uniqueness of IDs on a page , by modifying Ids to add a prefix. For example a composite component could be placed many times on a page, and the Ids of all its constituent components/controls must be unique. As a test example, when the above component was placed in the <head> section (i.e. not in a form), its clientId was j_idt4. When placed on the page a second time, in the form to show the control panel , its clientId was frmTest:j_idt9. Notice that by default the clientId was automatically prefixed by the form ID. This issue becomes important when Javascript is in use to refer to controls in the component, as the Id given to a control is in turn prefixed by the clientId. For example, when on the form, a select box which was given an Id of cmbTheme actually ended up with an id of frmTest:j_idt9:cmbTheme. This needs to be taken account of in the code. Note that in the Javascript examples in Chapter 9 of Core JavaServer Faces (p369), the form is inside the composite component. This turns things around, as the form ID is then prepended by the clientId of the composite component as the latter is a naming container – our case is different.
  • By default a form’s controls have the form id prefixed to their id, as the form is also a naming container. This behaviour can be disabled if desired by adding the attribute prependId=”false” to the form tag, but I did not do this.
  • JSTL functionality can be used such as c:if, and for example you can test parameters passed to composite components (cc.attrs.attrname)– the themeswitcher example uses this with the outputStyle attribute to determine whether to output a <link> tag for the theme stylesheet and set the theme base directory/default theme, or whether to output the themeswitcher control panel. The use of c:if in this way is a powerful means of controlling exactly what a custom component renders on the page, and is a useful alternative to using the render property on a component to prevent it being rendered. In addition, it can for example conditionalise the setting of backing bean properties from the page, as is done in the themeswitcher, which could not be done via toggling the render property on components.  In this case, it seemed more convenient and clearer to give two modes to the same component, so that all the design decisions where encapsulated and visible in one place, rather than inventing another component. Other examples of where this might be useful is where a general purpose composite component might be tailorable via its call attributes. For example a table component might have adjacent up/down buttons to allow re-ordering/moving of a block of selected rows, but the re-order capability might not always be needed, so it could be conditionally selected with c:if.
  • When using JSTL, there are limitations. As an example, I tried c:set to copy an attribute containing the backing bean reference to another variable, to use later in a subsequent instance of the composite component and save passing it twice. Setting a valueChangeListener using the saved copy of the bean reference gave a run time error and is not supported. However, reading and writing properties on the bean using the saved copy of the reference worked fine.
  • Note that other JSTL functions can also be used, e.g. to return the size of a string or list, as noted here.

Comments Off on JSF 2.0 Composite Components

November 11th, 2010
12:59 pm
Scrollable containers in Primefaces

Posted under CSS
Tags , , ,

Some Primefaces containers appear to support scrolling, but this is not universally supported. Layout panels support it, but ordinary panels appear not to.

Fortunately, with IE7 and above, scrolling on a <div> (JSF panelGroup with layout=”block”) works reliably and consistently across modern browsers, so scrolling can just be added within e.g. within a CSS class rule as follows:-

.ss-scroll {
   overflow:auto;
}

or:-

.ss-scroll {
   overflow: scroll;
}

Using overflow:auto will only add the scrollbars if they are needed, i.e. if content is clipped. Using overflow: scroll will add them all the time so you will get redundant scrollbars when the content does not clip.

Note that for Primefaces, to make a scrolling panel for example, the attribute needs to be added to a containing div inside the panel, and not the panel itself, otherwise the panel header will scroll out of view when the contents scroll which is undesirable.

The w3schools documentation on overflow will be found here.

No Comments »

November 11th, 2010
11:35 am
Fonts reduce in size when Primefaces table moved inside a panel

Posted under CSS
Tags , , , ,

Update 22/09/2011

The following selector (as documented below) did not work when used for a particular table. CSS ignored the rule presumably for reasons of specificity:-

.ss-nested-widget, .ss-nested-widget .ui-datatable {
     font-size: 100% !important;
}

However, the following selector did work (and was also modified to include a dialog as well as a table). This has the advantage of not relying on having ss-nested-widget as a class on the table in order to work.
This has now been adopted as standard as the solution for this issue :-

.ss-nested-widget,
.ui-widget .ui-datatable,
.ui-widget .ui-dialog { 
     font-size:100% !important;   
}

Original Post

This issue is due to font size inheritance.

My default font for all Primefaces components was specified globally as follows:-

.ui-widget {

font-size: 75% !important;

}

The reason for this is that in general it is considered more flexible to go for percentage sizes as these can then be scaled automatically when viewed on smaller devices.

Unfortunately, it appears that when for example a table is nested inside a panel, the font size appears to be 75% of 75% as the rule is inherited and applied twice, as 75% is a relative measurement, The table ends up rendered as a 9px font which is too small. The situation is further complicated by the fact that in the Primefaces skinning, there is a mixture of fonts specified in ems, percentages and pixel sizes, which means that not everything is specified in relative sizing anyway.

There are 2 solutions to the issue, both are straightforward, 1/ is the simplest although arguably not the best due to absolute sizing:-

1/ Change the global ui-widget rule above to use a fixed font size (12px works as a replacement for the above 75%)

.ui-widget {

font-size: 12px !important;

}

2/ Keep the  75%  for ui-widget and introduce a new rule to specify a 100% size for nested elements:-

.ss-nested-widget {

font-size:100% !important;

}

This rule needs to be introduced inside the panel. If it is placed on the panel itself, which is the parent element, then the font size just ‘goes large’ to 100%, i.e. larger than the desired default font. To obtain the correct behaviour, the sub-elements inside the panel must be tagged with the style class. It is possible to tag an enclosing <div> just inside the panel, so that the sub-elements inherit it. However, whilst this worked for input selectors and buttons in the panel, tables refused to play ball, and the following rule was needed to ensure that a table in the panel inherited the correct size:-

.ss-nested-widget, .ss-nested-widget .ui-datatable {

font-size: 100% !important;

}

The same kind of trick can be used to target other nested elements which do not inherit the correct size.

An alternative method would be just to add the class to sub-elements individually where required.

No Comments »

November 8th, 2010
3:11 pm
Changing Primefaces Structural CSS – Thin Panel example

Posted under JSF
Tags , , ,

Update 10/5/2011

The example project which contains this example is PrimeThemeSwitcherTableNonCC, on page ThinPanel.xhtml. This project may be found in the repository here.

Note that the styling for the repository version has changed slightly from below and is as follows:-

div.ss-thinpanel.ui-panel{
    padding:0px !important;
    border-top-width: 1px !important;
    border-right-width: 1px !important;
    border-bottom-width: 1px !important;
    border-left-width: 1px !important;
    margin-bottom: 1px !important;
}
.ss-thinpanel > div.ui-panel-titlebar {
    padding-top: 4px !important;
    padding-bottom: 3px !important;
    border:none !important;
}

 

Original Post

Sometimes it is desirable to change not the skin of a component but its structure – size, borders etc.
One example of mine was when I wanted an accordion like component which allows multiple panels to be open simultaneously. The accordion used to allow this but does not any longer. A good alternative to the accordion in this case is a stack of panel components, as they can all have independent expand/collapse buttons, and the close button is optional and so can be removed. As a bonus, a submenu can be added if desired as shown in the component showcase.

My issue with the panel for this use case was simply that it looked too chunky and took up too much real estate on the screen when a stack of them was present. I therefore produced some alternative structural CSS to produce a weight watcher’s version of panel, with the aim that a stack of them would take up no more vertical space than a similar stack of the same number of accordion tabs. In fact, in the end my weight watcher’s panel has ended up slightly slimmer than the accordion.

The following example page shows a stack of 3 standard ‘full fat’ panels followed by a similar stack of 3 of the thin version.
Note the following important points about the way the CSS is implemented:-

  • The CSS selectors are all driven by the CSS class ss-thinpanel. Simply including this in the styleClass attribute of the p:panel component enables the thin version.
  • As the new version is tied to the new class ss-thinpanel I have done nothing in CSS which would affect existing use of the panel component – as the example shows, the old can be used alongside the new.
  • The CSS overrides the structural CSS for the panel component, not the skinning CSS. This way, the changes work consistently across all the themes and do not require any theme changes to be made.
  • This technique is useful for any occasion where an alternative flavour of a component is needed – just ensure that the structural CSS is targeted (so all themes work), and drive the change by a new CSS class name. You can then have a number of alternative flavours of a component which are useable just by including the required classname.

<!DOCTYPE HTML>
<html xmlns="http://www.w3c.org/1999/xhtml"
   xmlns:f="http://java.sun.com/jsf/core"
   xmlns:h="http://java.sun.com/jsf/html"
   xmlns:p="http://primefaces.prime.com.tr/ui">
<f:view contentType="text/html">
<h:head>
    <link type="text/css" rel="stylesheet"
     href="#{request.contextPath}/resources/themes/eggplant/skin.css" />

<style type="text/css">       
        .ui-widget, .ui-widget .ui-widget {
            font-size: 75% !important;
        }
        div.ss-thinpanel.ui-panel {
            padding:0px !important;
            border-top-width: 1px !important;
            border-right-width: 1px !important;
            border-bottom-width: 1px !important;
            border-left-width: 1px !important;
            margin-bottom: 1px !important;
        }
        .ss-thinpanel > div.ui-panel-titlebar {
            padding-top: 3px !important;
            padding-bottom: 2px !important;
            border:none !important;
        }
    </style>
</h:head>
<h:body>
<h:form id="frmTest">
    <h:panelGroup layout="block" style="width:800px;">
        <p:panel toggleable="true" toggleSpeed="500" collapsed="true" header="F.C. Barcelona">
            <h:outputText value="FC Barcelona is one of only three clubs never to have been relegated from La Liga and is the most successful club in Spanish football along with Real Madrid,
            having won twenty La Liga titles, a record twenty-five Spanish Cups, eight Spanish Super Cups, four Eva Duarte Cups and two League Cups.
            They are also one of the most successful clubs  in European football having won fourteen official major trophies in total,
            including ten UEFA competitions. They have won three UEFA Champions League titles, a record four UEFA Cup Winners’ Cups,
            a record three Inter-Cities Fairs Cups (the forerunner to the UEFA Europa League), three UEFA Super Cups and one FIFA Club World Cup.
            The club is also the only European side to have played continental football in every season since its inception in 1955." />
        </p:panel>
        <p:panel toggleable="true" toggleSpeed="500" collapsed="true" header="F.C. Barcelona">
            <h:outputText value="FC Barcelona is one of only three clubs never to have been relegated from La Liga and is the most successful club in Spanish football along with Real Madrid,
            having won twenty La Liga titles, a record twenty-five Spanish Cups, eight Spanish Super Cups, four Eva Duarte Cups and two League Cups.
            They are also one of the most successful clubs  in European football having won fourteen official major trophies in total,
            including ten UEFA competitions. They have won three UEFA Champions League titles, a record four UEFA Cup Winners’ Cups,
            a record three Inter-Cities Fairs Cups (the forerunner to the UEFA Europa League), three UEFA Super Cups and one FIFA Club World Cup.
            The club is also the only European side to have played continental football in every season since its inception in 1955." />
        </p:panel>
        <p:panel toggleable="true" toggleSpeed="500" collapsed="true" header="F.C. Barcelona">
            <h:outputText value="FC Barcelona is one of only three clubs never to have been relegated from La Liga and is the most successful club in Spanish football along with Real Madrid,
            having won twenty La Liga titles, a record twenty-five Spanish Cups, eight Spanish Super Cups, four Eva Duarte Cups and two League Cups.
            They are also one of the most successful clubs  in European football having won fourteen official major trophies in total,
            including ten UEFA competitions. They have won three UEFA Champions League titles, a record four UEFA Cup Winners’ Cups,
            a record three Inter-Cities Fairs Cups (the forerunner to the UEFA Europa League), three UEFA Super Cups and one FIFA Club World Cup.
            The club is also the only European side to have played continental football in every season since its inception in 1955." />
        </p:panel>
    </h:panelGroup>
    <br/>
    <h:panelGroup layout="block" style="width:800px;">
        <p:panel toggleable="true" styleClass="ss-thinpanel" toggleSpeed="500" collapsed="true" header="F.C. Barcelona">
            <h:outputText value="FC Barcelona is one of only three clubs never to have been relegated from La Liga and is the most successful club in Spanish football along with Real Madrid,
            having won twenty La Liga titles, a record twenty-five Spanish Cups, eight Spanish Super Cups, four Eva Duarte Cups and two League Cups.
            They are also one of the most successful clubs  in European football having won fourteen official major trophies in total,
            including ten UEFA competitions. They have won three UEFA Champions League titles, a record four UEFA Cup Winners’ Cups,
            a record three Inter-Cities Fairs Cups (the forerunner to the UEFA Europa League), three UEFA Super Cups and one FIFA Club World Cup.
            The club is also the only European side to have played continental football in every season since its inception in 1955." />
        </p:panel>
        <p:panel toggleable="true" styleClass="ss-thinpanel" toggleSpeed="500" collapsed="true" header="F.C. Barcelona">
            <h:outputText value="FC Barcelona is one of only three clubs never to have been relegated from La Liga and is the most successful club in Spanish football along with Real Madrid,
            having won twenty La Liga titles, a record twenty-five Spanish Cups, eight Spanish Super Cups, four Eva Duarte Cups and two League Cups.
            They are also one of the most successful clubs  in European football having won fourteen official major trophies in total,
            including ten UEFA competitions. They have won three UEFA Champions League titles, a record four UEFA Cup Winners’ Cups,
            a record three Inter-Cities Fairs Cups (the forerunner to the UEFA Europa League), three UEFA Super Cups and one FIFA Club World Cup.
            The club is also the only European side to have played continental football in every season since its inception in 1955." />
        </p:panel>
        <p:panel toggleable="true" styleClass="ss-thinpanel" toggleSpeed="500" collapsed="true" header="F.C. Barcelona">
            <h:outputText value="FC Barcelona is one of only three clubs never to have been relegated from La Liga and is the most successful club in Spanish football along with Real Madrid,
            having won twenty La Liga titles, a record twenty-five Spanish Cups, eight Spanish Super Cups, four Eva Duarte Cups and two League Cups.
            They are also one of the most successful clubs  in European football having won fourteen official major trophies in total,
            including ten UEFA competitions. They have won three UEFA Champions League titles, a record four UEFA Cup Winners’ Cups,
            a record three Inter-Cities Fairs Cups (the forerunner to the UEFA Europa League), three UEFA Super Cups and one FIFA Club World Cup.
            The club is also the only European side to have played continental football in every season since its inception in 1955." />
        </p:panel>
    </h:panelGroup>
</h:form> 
</h:body>
</f:view>
</html>

No Comments »

November 8th, 2010
1:18 pm
Header width incorrect on Primefaces scrollable table

Posted under JSF
Tags , , , , ,

If a header facet is used on a Primefaces table, the header does not allow for the scrollbars if present. the column headers do adjust for the scrollbars (although there are issues with column alignment between the headers and the data – a number of such errors have been posted to the Primefaces forum).

One workaround for this is to selectively include a CSS selector to adjust the header <div> width when the scrollbars are present.
The following selector achieves this:-

<style type=”text/css”>       

    .ss-tableheader-scrolladjust > div.ui-datatable-header {
        width:495px;
    }
</style>

The following table definition selectively includes this when enough rows are present to require scroll bars (this must be derived empirically as it depends on the height of the table, font size used etc. :-

     <h:panelGroup layout=”block” style=”width:500px;”>    
     <p:dataTable var=”car” value=”#{tableBean.carsSmall}” scrollable=”true” 
         styleClass=”#{fn:length(tableBean.carsSmall) lt 8 ? ” : ‘ss-tableheader-scrolladjust’}” height=”200″ > 
         <f:facet name=”header”>
            Ajax Sorting        
         </f:facet>
         <p:column headerText=”Model”  sortBy=”#{car.model}”>
             <h:outputText value=”#{car.model}” />
         </p:column>

         <p:column headerText=”Year”  sortBy=”#{car.year}”>
             <h:outputText value=”#{car.year}” />
         </p:column>

         <p:column headerText=”Manufacturer”  sortBy=”#{car.manufacturer}”>
             <h:outputText value=”#{car.manufacturer}” />
         </p:column>

         <p:column headerText=”Color” sortBy=”#{car.color}”>
             <h:outputText value=”#{car.color}” />
         </p:column>
     </p:dataTable>
    </h:panelGroup>

No Comments »

November 5th, 2010
6:34 pm
Issues with JSF h:outputStylesheet and Primefaces/jQuery skinning

Posted under JSF
Tags , , , , ,

I tried to use this whilst experimenting with dyamic style sheets, but this support post here confirms that it does not work due to an issue with the way the images are referenced.
The symptom is that you get basically correct looking layout/colours but none of the images have loaded.
The solution is to use a link tag directly e.g.:-

<link type=”text/css” rel=”stylesheet”
href=”#{request.contextPath}/resources/themes/#{themeSelectorBean.theme}/skin.css” />

Whilst on the subject of h:outputStylesheet, it should be noted that for the following example:-

<h:outputStylesheet library=”css” name=”styles.css”/>

Whilst the href of the resulting generated link tag looks like this:-

<link href=”/context-root/faces/javax.faces.resource/styles.css?ln=css”
rel=”stylesheet” type=”text/css”/>

the actual physical directory containing the style sheet in this case will be

…\WebContent\resources\css\style.css

i.e. the logical to physical mapping of the web path in this case is not straightforward and obvious. If you just create the resources folder under your project’s WebContent folder and place all your libraries as subfolders under that, it should all work correctly (the above issue with jQuery/Primefaces notwithstanding)!

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 »

January 8th, 2010
5:35 pm
ICEfaces ice:form tag adds extra auto margin in IE7

Posted under JSF
Tags , , , ,

The ice:form tag renders a stateSavingMarker div which declares a couple of hidden fields for use by ICEfaces.

In IE7, (or IE8 in IE& compatibility mode), this div has its margin to auto which can cause an extra 10px or so margin to be added in between any elements outside the form and those inside.

This can be eliminated by adding a style to the form, either by adding a StyleClass attribute to refer to a CSS class, or by using the Style attribute to code an inline style. As this is a ‘one off’ just to clear a margin, the following example uses an inline style :-

<ice:form style=”margin:0″>

No Comments »

January 7th, 2010
7:28 pm
Styling tables with CSS

Posted under CSS
Tags , , ,

Rather than use the border keyword in HTML, it is better to style tables in CSS as this localises all the styling in the style sheet and promotes automatic re-use across different tables.

This page from Somacon is an easy-to-use ‘what if’ tool for tweaking all the properties for tables and instantly seeing the effect.

The w3schools reference page for tables may be found here.

This page also from w3schools describes the use of the border-collapse property, which causes the border-spacing and empty-cells properties to be ignored, and for all borders to be collapsed to a single border. This is very useful when you want complete control yourself and to prevent some of these other properties getting in the way, for example when you want a minimal flat solid border.

Note that as is often the case, incorrect HTML can give rise to strange behaviour. For example if you mistakenly set colspan to greater than the number of columns (as I did when I subsequently deleted a column after creating a table and forgot to reduce colspan) you may get a partial double border effect on the right hand side.

Here is an example page with a table illustrating these points, together with all its CSS and HTML.

No Comments »