Bits & Bytes

Posts Tagged ‘design’

The CSS Box Model

The CSS box model has four regions: the content region, the padding region, the border region, and the margin region. These regions can cause some confusion when coding CSS, so we have created some examples below for illustration. We start with the basic content region, which we can resize by setting the width and height parameter values. Then we add a border to the the content. Next, we put padding around the content area to separate it from the border. Finally, we add a margin to separate this content box from elements on the page via whitespace. Additionally, we add scroll bars to show what happens when the content does not fit within the content region.

Each web page is made elements that can exist within CSS boxes. Oftentimes the content that goes into these boxes, like images, has a set width and height. With text, we typically set the width and the height is determined by the amount of text in the box. However, we can set the width and height directly, and this will resize an image or set the bounds of the text area and so that we need to adjust scroll bars to see all of the text. When we set the width and height of the content region, we have to keep in mind the size of the overall box on the page.

width = 200 pixels
height = 100 pixels

To the left, we have a simple red box with black text that describes the width and height of the box, which we set with the style rules width: 200px; height: 100px;. The content region has no background color by default, but we set the color shown here by setting the background to red, using background-color: #FF0000. This box is simply the content region, which often holds text, like this one does, or an image. When the width and height properties are set like this, the values only apply to the content region and not the surrounding regions, as we will show. So, we have to keep that in mind when considering layout. None of the other regions are present in this example.

width = 200 pixels
height = 100 pixels

Some text that extends outside the box horizontally.

More text
More text
More text
More text

Sometimes the content extends beyond the bounds of the content region. For example, we might have more text than what will fit in the content box. When this is the case, the text will wrap at the specified width and extend outside of the box below it. Generally, we will want to keep the text inside of the content area and add scroll bars to allow the content to be viewed within the content region only. This can be accomplished by styling via an overflow rule, which can be set to always have scroll bars like this: overflow: scroll;. To the left, we have our original content region with some added content and scroll bars to allow all of the text to be read. Notice that the scroll bars are placed inside of the content region and take up some of the space there; they do not expand the width and height of the box.

width = 200 pixels
height = 100 pixels
border = 10 pixels

To give our content a more pleasing appearance, we can add a border to it. Borders can have many styles and serve as a frame for the content much as a picture frame on a picture. Border styles include: solid, dotted, dashed, and several others; we can also change the border’s color as well. To the left, we have added a dark gray border that is 10 pixels wide, using the style rule border: 10px solid #444444;. A typical border is usually much thinner than this, but we have made this one wide for greater visibility. Notice that in this case, the border does not use up content area like the scroll bars do, but it does add to the width and height of the overall box. So, the overall box width and height have the width and height of the content region plus the border: overall width = 220 pixels, overall height 120 pixels.

width = 200 pixels
height = 100 pixels
padding = 20 pixels
border = 10 pixels

Notice that the text inside the box above touches the border. This looks cluttered and makes the content more difficult to read. To make the content more pleasant looking and provide some much needed whitespace, we can use the padding region. To the left, we have set the padding to a width of 20 pixels on each side, using the style rule padding: 20px;. This helps to empasize the content by separating it from the border in much the same way that a matte does in a picture frame. Notice that the padding region is not visible. That is, it is is the same color as the background of the content area. In fact, we can consider the background region to be made up of the content region and the padding region. Also, notice that the padding region adds to the overall width and height of the box, so now we have: overall width = 260 pixels, overall height 160 pixels.

width = 200 pixels
height = 100 pixels
padding = 20 pixels
border = 10 pixels
margin = 30 pixels

Finally, we remark that the text outside of the box tends bump up against the border and give the layout a sloppy appearence. To fix this, we can add margins to the box to separate the border from the outside content. To the left, we have the same box as last time, except that we have added a 30 pixel margin on each side of the box, using the style rule margin: 30px. The margin region is not visible. It looks just like the surrounding area with the same backgound color. So, the margin merely serves as a spacing for the content to separate it from outside content. Again, this adds whitespace to our content box, which helps it to stand out and look less cluttered. Again, the margin adds to the size of the entire box for the element so that now we have: overall width = 320 pixels, overall height 220 pixels.

width = 200 pixels
height = 100 pixels
padding = 20 pixels
border = 10 pixels
margin = 30 pixels

Unfortunately in the previous box, we were not able to clearly see the content region, the padding region, and the margin region. That is because they share background colors with adjacent regions. To help clarify where these regions are, we have colored the content region and the margin region. To the left, we have the margin region that is 30 pixels wide on the outside in black. Inside this region, we have the border region that is 10 pixels wide in dark gray. Just inside of the border, we have the padding region which 20 pixels wide and is red, as it was before. Finally, in the middle, we have the content region, which has been changed to light gray. Notice that we have added the scroll bars again to illustrate that they appear in the content region. This box is the same size as the previous one. It is merely colored differently for illustration.

Notice that each of our content boxes were the same size 200 pixels by 100 pixels. However, the size of the entire box has expanded as we added the padding region, the border region, and the margin region. CSS offers finer control than what we have used, and we can set the width of the padding, border, and margin regions for each side individually. Given that, we can give the formulas for the width and height of the entire box as

overall width = width + (right and left padding)

+ (right and left border)

+ (right and left margin)

overall height = height + (top and bottom padding)

+ (top and bottom border)

+ (top and bottom margin)

UML Class Diagrams – part 5

Continued . . .

For this section, we pull together the material for modeling operations and attributes to give a specification of the full form and then discuss modeling for the appropriate level of detail. For attributes and operations, the name is always used, but the rest of the elements are optional. By convention, the class name is in the top box, followed by attributes and operations, respectively. This is the common convention that we have used and it is highly recommended, but UML does allow for any ordering.

For attributes, we have full form shown below. The name is mandatory, and the rest of the optional elements are shown in C++ template-style brackets ( < > ) to indicate that they are optional. First, we have the visibility, which is shown as +, #, , or ~ for public, protected, private, or package level visibility, respectively. Then we have the name. The attribute could contain multiple instances of its type; the allowed range of multiplicity can be specified in bracket notation like this [0..1], [n], or [0..*], which correspond to {0, 1}, {n}, or {0, 1, 2, … } in set notation, respectively. After this, we have a colon followed by the type. Then an “=” and an initial value. Finally, we have a the properties list, each of which may have a value setting.

Attributes

<visibility> name <Multiplicity> <: Type> <= InitialValue> <{Properties}> 
Properties
Property1 <= Value1>, ... 

For operations, the full form is shown below. Again, the optional elements are show in C++ template-style brackets. Just as with attributes, we have the visibility followed by the name. Inside the parentheses, we have the arguments, which can have a direction, name, type, and default value, as shown under the Arguments heading. After the arguments, we have a colon and the return type. Finally, we have the properties in braces, just as with the attributes.

Operations

<Visibility> Name(Arguments) <: ReturnType> <{Properties}>
Arguments
<Direction1> <ArgName1> <: ArgType1> <= DefaultValue1> ; ...
Properties
Property1 <= Value1> , ...

Below, we have a class for creating cubic polynomials. These are polynomials of the form

F(x) = c0x0 + c1x1 + c2x2 + c3x3

= c0 + c1x + c2x2 + c3x3,

where ci is a constant coefficient of the appropriate degree. The function F() is used to evaluate the polynomial at a particular value of x. For this class, we will assume that a constructor exists (not shown) that initializes the cubic to be the zero polynomial (all zero coefficients).

class CCubic
{
public:
    double F(double dX = 0.0) const;
private:
    double mdaC[4];
};

This class can be diagramed in UML, as shown below, with in the fullest form for attributes and operations. Here, we use the assumption that the cubic is initialized in a constructor somewhere to be the zero polynomial; of course, that make the polynomial a constant and not a cubic. The coefficients can be changed, so we indicate that with the “changeable” property. Also, the function F() is “const” because does not change the values of the coefficients. Moreover, it is statically bound. Therefore, we have modeled it with the property specifications “isQuery” and “leaf” to indicate these properties.

This an elaborate specification, but is reasonable for modeling a simple class like this. However, for a diagram with many attributes and operations, this level of detail can get messy and difficult to read. Moveover, many of the details may not be relevant in a given context. For example, when designing this class it is probably not very important what the initial values of the coefficients are or the default value of dX in the function F(). So, we might use the cleaner version below.

Likewise, the fact that the coefficients are “changeable” is probably obvious as are the properties of the function F(). Furthermore, the use of doubles is probably clear and may not even be material to the design. So, we can throw those out as well as the obvious fact that dX is an input parameter. Our greatly simplified diagram now looks like this.

Finally, in a larger context, we may only be concerned that a cubic class exists and we can throw out the attributes and operations entirely, as we demostrate below. Notice that our diagram has three compartments, even though two ar empty. In this case, we could use simply one compartment with the class name or we could use three like this to indicate that it is important to keep in mind that this class has attributes and operations.

UML Class Diagrams – part 4

Continued . . .

In this section, we give the final details of the attributes and operations that can be modeled with UML. With the central elements covered, we are going to add some examples of attributes with initial values and operations with default argument values. Additionally, we will give some examples of attributes and operations with properties, and we will talk about some of the commonly used properties. Finally, we will show how to of model scope and operation binding.

Our arc class below, called CAArc, should serve to illustrate the remaining elements of UML that can be modeled for operations and attributes. This class contains three operations and three attributes. Of the operations, two are instance operations and the third is a class operation. The word static is used in C++ to indicate a class member, rather than an instance member. The word virtual before GetLength() indicates that that function has dynamic binding, while GetOrientation() is statically, or compile-time, bound. Also, the ” = 0″ is used to indicate that GetLength() is not implemented for this class, but rather is a pure virtual function or an abstract operation.

Of the classes attributes, two are instance members and one, the constant skdPi, is a class member. The constant is initialized at compile-time to the value 3.14159. The other member variables, dStartAngle and dEndAngle, have no initial value that is apparent here and are non-constant, so they can be changed at anytime.

class CAArc
{
public:
    virtual double GetLength() = 0;
    int GetOrientation();
    static double GradToDeg(double dA = 0.0);
private:
    static const double skdPi = 3.14159;
    double dStartAngle;
    double dEndAngle;
};

The arc class above can be modeled in UML using the diagram below. Since the GetLength() is an abstract operation, we italicize it to show this. We use the property “leaf” to indicate that the operation GetOrientation() is statically bound and can not be overridden. The operation is GradToDeg() has an argument with a default argument value, as shown. Also, we have underlined GradToDeg() to show that it is a class operation. Likewise, we underline skdPi, since it is a constant with class scope. The initial value for skdPi is shown along with the qualifier “frozen” to indicate that this is a constant. The instance members dStartAngle and dEndAngle are just ordinary member variables.

As far as properties, notice that the constant skiPi has the property “frozen” after it and the function GetOrientation() has the property “leaf” after it. However, we also have the property “changeable” on our instance variables. This can be used with attributes to specify that the variable’s value can be changed. We can also use “addOnly” on attributes with multiplicity to indicate that the values can only be added, say to an array, for instance. For operations, we can use the property “isQuery” to indicate that the operation does not change values; this is the C++ equivalent of a function that is constant. Additionally, we can specify operations having the properties “sequential”, “guarded”, or “concurrent” in the context of processes and threads.

To be continued . . .