Build a complex layout in CSS is not easy. The Microsoft WPF library, available under .NET, is used to describe UIs with XML tagged language. The designers of this library offer “panel” controls (like elements in HTML) whose purpose is to specify the layout of the elements of the UI (other panels, texts, images, etc …).
The properties of these controls direct the designer UI to other element disposition specification paradigms, which breaks with CSS’s own presentation flow control model.
Making a port in HTML / Javascript of these controls makes it possible in a WEB page to have the HTML elements in a simpler way than in CSS. By leveraging native HTML / CSS capabilities, the amount of code needed to manage controls is limited, and the new elements are close to W3C standards (respect for semantics and accessibility).
This article presents the wpanels.js Javascript library.
wpanels is a set of HTML elements and javascript classes that provides porting of layout WPF controls as well as other extended layout controls.
I. WPF panels and their main properties
I.1. The panel controls
The following table lists the WPF panels. The Canvas panel is removed from the list because it looks like a clone of its HTML counterpart
control | description |
---|---|
Stack Panel | arranges the elements one after the other or below each other. gets bigger with the content |
Wrap Panel | like the StackPanel, but manages the wrapping of elements on several lines. does not get bigger with the content |
Dock Panel | layout panel, provides docks at the top, left, right and bottom of the area filled by the panel. The central part receives an element that automatically fills the surface. the docks get bigger with the content, not the panel |
Grid Panel | layout panel. arranges its elements in a table structure of rows and columns. similar to its html counterpart, but offers more possibilities: multiple elements in a cell on top of each other, elements that can span multiple rows and / or columns, and layout properties specific to wpf controls. This is by far the most powerful and most used wpf panel |
I.2. layout properties
WPF controls have all common layout properties:
property | description |
---|---|
width, height | the size can be fixed (default value in pixel, the unit can be specified among: px, in, cm, pt) or automatic (the control adapts its size to its contents, value: Auto, insensitive case). for wpf the pixel size is device independent and is 1/96 inch per unit |
minWidth, minHeight | minimum size adoptable by the control. Same syntax as width, height |
maxWidth, maxHeight | maximum size adoptable by the control. Same syntax as width, height |
horizontalAlignment | indicates how the control is docked horizontally in its container. possible values are Left, Center, Right, Stretch. Stretch induces the auto-size behavior on the control (expands to the size of the container) otherwise the control is adapted to the size of its contents. note that this property may contradict the width property. It is this which prevails |
verticalAlignment | indicates how the control is docked vertically in its container. the possible values are Top, Center, Bottom, Stretch. note that this property may contradict the height property. It is this which prevails |
margin | the margin is the extra space outside the control. the value of a margin is a fixed quantity |
padding | the padding is the extra space inside the control. the value of a padding is a fixed size |
and controls with content also have the following properties:
property | description |
---|---|
horizontalContentAlignment | as horizontalAlignment, gives the layout of the contents of the control in relation to it |
verticalContentAlignment | as verticalAlignment and same effect as horizontalContentAlignment |
to understand the effect of horizontal and vertical alignment properties, look at the following diagram::
II. Porting to html / js: Grid case
The Grid being the most complex layout panel, it serves as reference case for the development of new html controls and their mode of management
II.1. Container properties
Properties are used to declare each column and each row of the grid and specify its size (or size behavior).
These properties are described by the RowDefinitions and ColumnDefinitions collection properties, which receive RowDefinition and ColumnDefinition type items, respectively.
Row and column sizes (GridLength) can be defined as an absolute quantity, a percentage, or an automatic size:
type value | description |
---|---|
auto | adjusted to the size of the content |
fixed | fixed size (value: number). The overflow is clipped |
star | star (value: *). The size is increased to occupy all available space, obtained after all auto and fixed sizes have been set. if there are multiple rows / columns of size *, the available space is shared proportionally. The proportionality value can be set to size by specifying a number before the star. For example 2 * and 8 *, are identical to 20 * and 80 * indicate proportionality of 20% and 80%. Size proportionality can only be applied if the Grid does not have a size set to auto (fit to the size of the content) |
II.2. Porting XAML Syntax to HTML
A Grid can be described as follows in XAML:
<Grid Width="auto" MinWidth="100" MinHeight="100" MaxWidth="800" MaxHeight="600" HorizontalAlignment="Left" VerticalAlignment="Stretch" ShowGridLines="true" > <!-- rows definitions : 4 rows --> <Grid.RowDefinitions> <RowDefinition Height="auto"/> <RowDefinition Height="120"/> <RowDefinition Height="4*"/> <RowDefinition Height="6*"/> </Grid> <!-- columns definitions : 2 columns --> <Grid.ColumnDefinitions> <ColumnDefinition Width="auto"/> <ColumnDefinition Width="auto"/> </Grid> <!-- grid content --> <Label Grid.Row="0" Grid.Column="0" Background="Yellow" > cell 1,1 </label> <label Grid.Row="1" Grid.Column="1" Grid.RowSpan="2" Grid.ColumnSpan="2" Background="Cyan" > cell 1,1 to 2,2 </label> </Grid>
This grid definition produces the following result in a WPF window:
The purpose of the new wpanel elements is to mix current HTML elements and layout panels. We will introduce new tags in html and enrich existing elements with new attributes. Some existing attributes (common with WPF, such as width and height) can be reused with rich value semantics. The syntax choices are:
syntax | description |
---|---|
tags | the tags added to html are compound names (standard), with the prefix wp , the name of these new tags takes the names of classes WPF with lettering in camel-case except the first letter in lowercase (mix between norm html and C #) . For example, wp-grid is the name of the Grid element. |
attributes | added attributes on new elements have no prefix (syntax lightening), while for clarity those added to existing HTML elements take the wp prefix . The names of the attributes are written in camel-case except the first letter in lowercase |
values | new values are added to the existing html attributes width and height, to use the wpf: Auto (insensitive case) syntax . Native html values are always allowed and increase the possibilities provided by wpf. For the wp-columnDefinition and wp-rowDefinition elements, the width and height attributes only accept the wpf ( * , n * , auto , Auto , n with n numeric value) syntaxes . Keyword values are analyzed independently of the breakage |
previous example in the wpanels syntax:
<wp-grid width="auto" minWidth="100" minHeight="100" maxWidth="800" maxHeight="600" horizontalAlignment="left" verticalAlignment="stretch" showGridLines="true"> <!-- rows definitions --> <wp-rowDefinitions> <wp-rowDefinition height="auto"/> <wp-rowDefinition height="120"/> <wp-rowDefinition height="4*"/> <wp-rowDefinition height="6*"/> </wp-rowDefinitions> <!-- columns definitions --> <wp-columnDefinitions> <wp-columnDefinition width="auto"/> <wp-columnDefinition width="auto"/> </wp-columnDefinitions> <!-- content --> <span wp-row="0" wp-column="0" style="background-color:yellow"> cell 1,1 </span> <span wp-row="1" wp-column="1" wp-rowSpan="2" wp-colSpan="2" style="background-color:cyan"> cell 1,1 to 2,2 </span> </wp-grid>
II.3. Porting layout properties in CSS / JS
element | property | Implementation |
---|---|---|
WPanel (FrameworkElement) | élément | translated by HTMLElement, display: block. root of all the elements that make the control. |
width | • fixed size in pixels: supported as is by the html element. if the width property is set to a fixed size, a setting of horizontalAlignment to Stretch will be ignored. the attribute must be omitted to prevent Stretch on horizontalAlignment (width at precedence). • the auto value causes the width attribute to be removed and cancels the Stretch effect on horizontalAlignment • the absence of the attribute causes default auto |
|
height | similar to width | |
minWidth | desired minimum width (fixed value). the order of precedence is minWidth, maxWidth, width | |
minHeight | desired minimum height | |
maxWidth | desired maximum width | |
maxHeight | maximum height desired | |
horizontalAlignment | • left : to remain compatible with the placement of the element in the document flow (ex: float: left), the left position is managed by js • right : similar to left • center : similar to left • stretch : the automatic enlargement is managed by js. the size of the element is extended until it is container or the element itself even if it is not in a container until it covers the available space (to the right up to the element visually to right) |
|
verticalAlignment | similar in all respects to horizontalAlignment | |
horizontalContentAlignment | left : the elements in the container are aligned to the left of the container according to the nature of the container right : the elements in the container are aligned to the right of the container according to the nature of the container center : the elements in the container are aligned with the container center of it depending on the nature of the container stretch : the elements in the container are stretched horizontally in it depending on the nature of the container |
|
verticalContentAlignment | similar to horizontalContentAlignment |
element | property | Implementation |
---|---|---|
Grid | represented by the HTMLElement wp-grid which contains an element of type table or div (display: table) | |
contenu de Grid | wp-row | numeric value> = 0 <nbRows, the element is transferred to the corresponding cell element td or div (display: table-cell) |
wp-column | numeric value> = 0 <nbCols, the element is transferred to the corresponding cell element | |
wp-rowSpan | the element must float above the covered lines, its height is calculated by js | |
wp-colSpan | the element must float above the covered columns, its width is calculated by js |
to be continued…