⭐ If you would like to buy me a coffee, well thank you very much that is mega kind! : https://www.buymeacoffee.com/honeyvig Hire a web Developer and Designer to upgrade and boost your online presence with cutting edge Technologies
Showing posts with label web design tips. Show all posts
Showing posts with label web design tips. Show all posts

Thursday, January 31, 2013

Design Centric And Layered CSS Files

One of the ideas I always find myself coming back to is separating different aspects of design into layers. Typography on one layer, color on another, grids on yet another. By constraining all, but one layer, the unconstrained layer can be more deeply explored.

One way I think about this is how to best organize css files to take advantage of this layered approach to design. My thinking is a design centric approach to stylesheet organization would allow for better experimentation and learning and possibly make maintenance easier.
I’ve struggled in the past trying to implement (and perhaps explain) this idea and I suspect what I’m looking for lies in some recent css thought that I’ve yet to look into fully.
  • Revising flawed practices
  • OOCSS and SMACSS
  • CSS preprocessors
My aim with this post is to serve as an introduction into the above, from the perspective of this design centric css concept. It’s also here to push me a little into looking deeper into each of the 3 topics and to jot down some general thoughts and ideas.
Layers of fabric

Layered Design

The basic idea is relatively simple. It’s that we can learn, work on, or maintain, one aspect of design independently of others. Imagine you’re working on an existing design and you’d like to overhaul the color scheme. You should be able to work on this without having to make changes to the typography or underlying grid the site is built on.
This can be a great way to learn design. With so many different things to learn and practice and it’s impossible to tackle them all at once. The same way we set constraints before beginning a project we can set constraints on our learning and limit the design palettes we work with in order to experiment with fewer things at once.
Of course, for a design to be most effective it needs a sense of unity and harmony across all these layers. Picture one set of parallel planes, each representing a design layer, and another set of parallel planes representing things like unity and concept that cut across the first set of planes connecting them.
  • Typography
  • Layout/grid
  • Color
  • Imagery
  • General aesthetics
  • Content
  • Interaction/experience layer
There’s no question that the above work best when they work in harmony with each other. Any grid you create would naturally be based on something like type or image sizes. The point is that we could study grids better by holding to a fixed set of typographic characteristics or holding colors to grayscale while we explore different font choices and type characteristics.
Texture woven into a circular layered pattern

A Design Centric and Layered Approach to CSS

I think most of us write css top down. We style the main header or masthead and work our way down the design through content areas and asides, until we reach the footer. We end up with our css organized around these large sections of our layout.
We probably also have sections for a base set of styles and another for common classes we use throughout our html, and perhaps a set of reset styles. The css for our main navigation bar is all in one place as is the css for your sidebar.
This approach is easy when developing as we code in the same order as we see elements in the design and it makes sense if your goal in maintenance is to rework your entire navigation to have all the navigation code located in one place.
There’s nothing wrong with the above, but I wonder is this how we can best maintain a site? Is it truly how we’d realign a design.
Isn’t it just as likely we’d want to change the entire color scheme of a site as we’d want to solely rework the navigation bar? Might we want to modify a site’s layout without altering the general aesthetics of buttons, and other design elements?
Lately I’ve found myself wanting to change something like the baseline grid for a design and with this top down approach the styles affecting the baseline are located throughout the entire file. It would be much easier if those styles were all located in one place or at least set up to be more easily changed.
For example take something like the following.
1
2
3
#primary {
  margin: 2em 12.5% 3em 0;
}
Right and left margins are more aligned with layout. Top and bottom margins are more connected to a baseline grid. Now consider the above rewritten as
1
2
3
4
5
6
7
8
9
10
11
12
/* -- placed in a layout section -- */
#primary {
  margin-left: 2em;
  margin-right: 0;
}

/* -- placed in a baseline subsection
      within a general typography section -- */
#primary {
  margin-top: 2em;
  margin-bottom:3em;
}
It’s certainly more code, but I wonder how much easier a set up like this would be when wanting to change only the baseline or only the layout.
Naturally whether or not this is easier to maintain depends on what you’re more likely to modify after the initial design is complete. Are you more likely to rework your footer without touching your header or are you more likely to change the color scheme affecting both while leaving the type intact. Of late I’ve begin to think it’s the latter more than the former.
There are a couple of problems I’ve encountered when trying to develop with this approach in mind.
  • It’s easier to develop initially with a top down approach.
  • It’s not always clear in advance what you’ll want to change, confusing how best to organize things.
  • Some styles seem appropriate in multiple sections.
With the first it could simply be a matter of being used to a certain way of developing. However, I get the feeling top down is generally easier to start with and that refactoring the code would become necessary to organize how I want. It’s an extra step though. With the latter two items it’s hard to know in advance what’s going to be better.
Reading glasses

Where to Look Next

While I’ve been thinking about all this some new thought about css in general has gained prominence.
The idea of revising some flawed practices comes from Nicole Sullivan who’s suggested some of the things we hold as absolutes in the way we code shouldn’t be seen so absolutely. They were developed years ago under a different landscape and it’s time to rethink them.
OOCSS and SMACSS come out of this rethinking and are ways to develop more around reusable classes and to organize our css around these reusable classes.
I think in the end what I’m looking for will be found mainly in css preprocessors like Sass and Less. If you’ve been playing along as you’ve read this post, the thought of being able to use variables has possibly come across your mind once or twice. However I suspect the first two will also contribute to what I’m after.
In any event I’d like to explore each of the above topics in the coming weeks. If you’ve already looked more deeply than I have into any of them please share your thoughts, especially in regards to how they might fit into my design centric and layered approach to css files.

Saturday, January 26, 2013

6 Methods For Vertical Centering With CSS

Centering elements vertically with css is something that often gives designers trouble. There are however a variety of methods for vertical centering and each is fairly easy to use. Today I want to present 6 of those methods.

I’ve usually skipped over the topic of vertical centering, since there are some good posts already out there that are easy enough to find, but recently someone requesting a tutorial on vertically centering so I thought why not.

Let’s start by first talking about something that doesn’t work as many expect. Understanding why vertical-align doesn’t always work will help us better understand vertical centering in general.
abstract photograph of vertical light

Vertical-Align

Horizontal centering with css is rather easy. When the element to be centered is an inline element we use text-align center on its parent. When the element is a block level element we give it a width and set the left and right margins to a value of auto.
With text-align: center in mind, most people look first to vertical-align in order to center things vertically. It seems logical and I know it was my first choice. If you’ve come from table based layout you likely used the valign attribute, which would also lead you to believe vertical-align is the way to go.
However valign only worked on table cells. Vertical-align is similar. It also applies to table cells and it works with some inline elements.
The values for vertical-align have meaning with respect to a parent inline element.
  • With a line of text the values are relative to the line-height.
  • With a table cell the values are relative to the table-height-algorithm, which usually means the height of the row.
Unfortunately vertical-align doesn’t apply to block-level elements like a paragraph inside a div, which is where most of us figure out it isn’t the be all solution to vertical centering.
All is not lost though, as we have other methods for centering block level elements and we can still use vertical-align where appropriate. Which method you choose will depend on what you’re trying to center relative to its container element.
line height demo

Line-Height Method

This method will work when you want to vertically center a single line of text. All we need to do is set a line-height on the element containing the text larger than it’s font-size.
By default equal space will be given above and below the text and so the text will sit in the vertical center.
Most tutorials will also set the height on the element with the same value given to the line-height. I don’t think setting the height is necessary, but if line-height alone doesn’t work for you setting the height of the element will likely be the solution.

html

1
2
3
<div id="parent">
    <div id="child">Text here</div>
</div>

css

1
2
3
#child {
    line-height: 200px;
}
The above works in all browsers, however it will only work for a single line of text. If your text could wrap to a 2nd line you need to use a different method. The value of 200px above is arbitrary. You can use any value you want as long as it’s larger than the font-size that’s been set.
Added: As Jeff pointed out in the comments below, there’s one small got’cha with this method in that you have to be careful when using the shortcut for the font property. This method relies on you setting the line-height as a value greater than the font-size. When you use the font shortcut any property you don’t specifically set gets set to its default value. With line-height that default is 1. If you use the font shortcut, just make sure to explicitly set the line-height inside.

Centering an Image with Line-Height

What if the content you want centered is an image? Will this method work? The answer is yes with one additional line of css.

html

1
2
3
<div id="parent">
    <img src="image.png" alt="" />
</div>

css

1
2
3
4
5
6
7
#parent {
    line-height: 200px;
}

#parent img {
    vertical-align: middle;
}
You set the line-height as we did above (It’ll need to be greater than the height of the image) and then set vertical-align: middle on the image.
table cell demo

CSS Table Method

Above I mentioned that vertical-align applies to table cells which leads us to this method. We’ll display our elements as table and table cell and then use the vertical-align property to center the content.
Note: CSS tables are not the same as html tables.

html

1
2
3
<div id="parent">
    <div id="child">Content here</div>
</div>

css

1
2
3
4
5
6
#parent {display: table;}

#child {
    display: table-cell;
    vertical-align: middle;
}
We set the parent div to display as a table and the child div to display as a table-cell. We can then use vertical-align on the child div and set it’s value to middle. Anything inside this child div will be vertically centered.
Unlike the method above the content can be dynamic as the div will grow with what’s placed inside. The downside of this method is it doesn’t work in older versions of IE, though there is a fix, which is to add display: inline-block to the child element.
1
2
3
#child {
    display: inline-block;
}
absolute positioning and negative margin demo

Absolute Positioning and Negative Margin

This method works for block level elements and also works in all browsers. It does require that we set the height of the element we want to center.
In the code below I’m centering the child both vertically and horizontally using this method.

html

1
2
3
<div id="parent">
    <div id="child">Content here</div>
</div>

css

1
2
3
4
5
6
7
8
9
10
#parent {position: relative;}

#child {
    position: absolute;
    top: 50%;
    left: 50%;
    height: 30%;
    width: 50%;
    margin: -15% 0 0 -25%;
}
We begin by positioning both parent and child divs. Next we set the top and left values of the child to be 50% each, which would be the center of the parent. However this sets the top left corner to be in the center so we’re not done.
We need to move the child up (by half its height) and to the left (by half its width) so it’s center is what sits in the center of the parent element. This is why we need to know the height (and here the width) of the child element.
To do that we give the element a negative top and left margin equal to half its height and width.
Unlike the first 2 methods this one is meant for block level elements. It does work in all browsers, however the content can outgrow its container in which case it will disappear visually. It’ll work best when you know the heights and widths of the elements.
absolute positioning and vertical stretching demo

Absolute Positioning and Stretching

As with the method above this one begins by setting positioning on the parent and child elements as relative and absolute respectively. From there things differ.
In the code below I’ve once again used this method to center the child both horizontally and vertically, though you can use the method for vertical centering only.

html

1
2
3
<div id="parent">
    <div id="child">Content here</div>
</div>

css

1
2
3
4
5
6
7
8
9
10
11
12
#parent {position: relative;}

#child {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    width: 50%;
    height: 30%;
    margin: auto;
}
The idea with this method is to try to get the child element to stretch to all 4 edges by setting the top, bottom, right, and left vales to 0. Because our child element is smaller than our parent elements it can’t reach all 4 edges.
Setting auto as the margin on all 4 sides however causes opposite margins to be equal and displays our child div in the center of the parent div.
Unfortunately the above won’t work in IE7 and below and like the previous method the content inside the child div can grow too large causing it to be hidden.
vertical centering with padding demo

Equal Top and Bottom Padding

In the method above we allowed the browser to automatically set the margins of the child element so they would be equal. In this method we’ll do something similar and explicitly set the top and bottom padding of the parent to be equal.

html

1
2
3
<div id="parent">
    <div id="child">Content here</div>
</div>

css

1
2
3
4
5
6
7
#parent {
    padding: 5% 0;
}

#child {
    padding: 10% 0;
}
In the css above I’ve set top and bottom paddings on both elements. Setting it on the child will make sure the contents in the child will be vertically centered and setting it on the parent ensures the entire child is centered within the parent.
I’m using relative measurements to allow each div to grow dynamically. If one of the elements or it’s content needs to be set with an absolute measurement then you’ll need to do some math to make sure things add up.
For example if the parent was 400px in height and the child 100px in height we’d need 150px of padding on both the top and bottom.
150 + 150 + 100 = 400
Using % could throw things off in this case unless our % values corresponded to exactly 150px.
This method works anywhere. The downside is that depending on the specifics of your project you may need to do a little math. However if you’re falling in line with the idea of developing flexible layouts where your measurements are all relative you can avoid the math.
Note: This method works by setting paddings on the outer elements. You can flip things and instead set equal margins on the inner elements. I tend to use padding, but I’ve also used margins with success. Which you choose would depend on the specifics of your project.
vertical centering with floater div demo

Floater Div

This last method requires an empty div which is floated and used to control where our child element sits in the document flow. Notice the floater div comes before our child div in the html below.

html

1
2
3
4
<div id="parent">
    <div id="floater"></div>
    <div id="child">Content here</div>
</div>

css

1
2
3
4
5
6
7
8
9
10
11
12
13
#parent {height: 250px;}

#floater {
    float: left;
    height: 50%;
    width: 100%;
    margin-bottom: -50px;
}

#child {
    clear: both;
    height: 100px;
}
We float the empty div to the left (or right) and give it a height of 50% of the parent div. That causes it to fill up the entire upper half of the parent element.
Because this div is floated it’s removed from the normal document flow so we need to clear the child element. Here I’ve used clear: both, but you just need to clear in the same direction you floated the empty floater div.
The top edge of the child div should now be immediately below the bottom edge of the floater div. We need to bring the child element up by an amount equal to half it’s height and to do so we set a negative margin-bottom on the floater div.
This method also works across browsers. The downside is that it requires an empty div and that you know the height of the child element.

Additional Resources

In the sections above I linked to articles specific to each method. Below are some resources that cover more than a single method for centering.
verticle fence posts

Summary

None of the methods above is complicated and I’m sure if you use each once or twice it’ll be easy to use again.
The difficultly if there is one is that none of the methods above is perfect for all occasions. The trick is to understand several of the above and use each appropriately.
Some of the methods work better for inline elements and others work better for block level elements. Some might work better with your preference for developing a layout and some don’t work in older versions of a certain browser we all know well.
Rarely do I vertically center elements in a design. When I do the methods I tend to use are the line-height method and the equal padding method. One or the other has always worked for my needs.
If neither worked I would reach for either the positioning or floater methods and save the table cell method as a last resort. In time we’ll be able to use the css3 flexible box layout module and forget about the methods above, but for now browser support isn’t quite there.
Do you use any of the above methods or do you use a different method I didn’t mention? Is there a vertical centering issue that none of the methods here address?