original source : http://www.howtogeek.com/177621/the-beginners-guide-to-iptables-the-linux-firewall/

About iptables

iptables is a command-line firewall utility that uses policy chains to allow or block traffic. When a connection tries to establish itself on your system, iptables looks for a rule in its list to match it to. If it doesn’t find one, it resorts to the default action.

iptables almost always comes pre-installed on any Linux distribution. To update/install it, just retrieve the iptables package:

sudo apt-get install iptables

There are GUI alternatives to iptables like Firestarter, but iptables isn’t really that hard once you have a few commands down. You want to be extremely careful when configuring iptables rules, particularly if you’re SSH’d into a server, because one wrong command can permanently lock you out until it’s manually fixed at the physical machine.

Types of Chains

iptables uses three different chains: input, forward, and output.

Input – This chain is used to control the behavior for incoming connections. For example, if a user attempts to SSH into your PC/server, iptables will attempt to match the IP address and port to a rule in the input chain.

Forward – This chain is used for incoming connections that aren’t actually being delivered locally. Think of a router – data is always being sent to it but rarely actually destined for the router itself; the data is just forwarded to its target. Unless you’re doing some kind of routing, NATing, or something else on your system that requires forwarding, you won’t even use this chain.

There’s one sure-fire way to check whether or not your system uses/needs the forward chain.

iptables -L -v

The screenshot above is of a server that’s been running for a few weeks and has no restrictions on incoming or outgoing connections. As you can see, the input chain has processed 11GB of packets and the output chain has processed 17GB. The forward chain, on the other hand, has not needed to process a single packet. This is because the server isn’t doing any kind of forwarding or being used as a pass-through device.

Output – This chain is used for outgoing connections. For example, if you try to ping howtogeek.com, iptables will check its output chain to see what the rules are regarding ping and howtogeek.com before making a decision to allow or deny the connection attempt.

The caveat

Even though pinging an external host seems like something that would only need to traverse the output chain, keep in mind that to return the data, the input chain will be used as well. When using iptables to lock down your system, remember that a lot of protocols will require two-way communication, so both the input and output chains will need to be configured properly. SSH is a common protocol that people forget to allow on both chains.

Policy Chain Default Behavior

Before going in and configuring specific rules, you’ll want to decide what you want the default behavior of the three chains to be. In other words, what do you want iptables to do if the connection doesn’t match any existing rules?

To see what your policy chains are currently configured to do with unmatched traffic, run theiptables -L command.

As you can see, we also used the grep command to give us cleaner output. In that screenshot, our chains are currently figured to accept traffic.

More times than not, you’ll want your system to accept connections by default. Unless you’ve changed the policy chain rules previously, this setting should already be configured. Either way, here’s the command to accept connections by default:

iptables --policy INPUT ACCEPT
iptables --policy OUTPUT ACCEPT
iptables --policy FORWARD ACCEPT

By defaulting to the accept rule, you can then use iptables to deny specific IP addresses or port numbers, while continuing to accept all other connections. We’ll get to those commands in a minute.

If you would rather deny all connections and manually specify which ones you want to allow to connect, you should change the default policy of your chains to drop. Doing this would probably only be useful for servers that contain sensitive information and only ever have the same IP addresses connect to them.

iptables --policy INPUT DROP
iptables --policy OUTPUT DROP
iptables --policy FORWARD DROP

Connection-specific Responses

With your default chain policies configured, you can start adding rules to iptables so it knows what to do when it encounters a connection from or to a particular IP address or port. In this guide, we’re going to go over the three most basic and commonly used “responses”.

Accept – Allow the connection.

Drop – Drop the connection, act like it never happened. This is best if you don’t want the source to realize your system exists.

Reject – Don’t allow the connection, but send back an error. This is best if you don’t want a particular source to connect to your system, but you want them to know that your firewall blocked them.

The best way to show the difference between these three rules is to show what it looks like when a PC tries to ping a Linux machine with iptables configured for each one of these settings.

Allowing the connection:

Dropping the connection:

Rejecting the connection:

Allowing or Blocking Specific Connections

With your policy chains configured, you can now configure iptables to allow or block specific addresses, address ranges, and ports. In these examples, we’ll set the connections to DROP, but you can switch them to ACCEPT or REJECT, depending on your needs and how you configured your policy chains.

Note: In these examples, we’re going to use iptables -A to append rules to the existing chain. iptables starts at the top of its list and goes through each rule until it finds one that it matches. If you need to insert a rule above another, you can use iptables -I [chain] [number] to specify the number it should be in the list.

Connections from a single IP address

This example shows how to block all connections from the IP address 10.10.10.10.

iptables -A INPUT -s 10.10.10.10 -j DROP

Connections from a range of IP addresses

This example shows how to block all of the IP addresses in the 10.10.10.0/24 network range. You can use a netmask or standard slash notation to specify the range of IP addresses.

iptables -A INPUT -s 10.10.10.0/24 -j DROP

or

iptables -A INPUT -s 10.10.10.0/255.255.255.0 -j DROP

Connections to a specific port

This example shows how to block SSH connections from 10.10.10.10.

iptables -A INPUT -p tcp --dport ssh -s 10.10.10.10 -j DROP

You can replace “ssh” with any protocol or port number. The -p tcp part of the code tells iptables what kind of connection the protocol uses.  If you were blocking a protocol that uses UDP rather than TCP, then -p udp would be necessary instead.

This example shows how to block SSH connections from any IP address.

iptables -A INPUT -p tcp --dport ssh -j DROP

Connection States

As we mentioned earlier, a lot of protocols are going to require two-way communication. For example, if you want to allow SSH connections to your system, the input and output chains are going to need a rule added to them. But, what if you only want SSH coming into your system to be allowed? Won’t adding a rule to the output chain also allow outgoing SSH attempts?

That’s where connection states come in, which give you the capability you’d need to allow two way communication but only allow one way connections to be established. Take a look at this example, where SSH connections FROM 10.10.10.10 are permitted, but SSH connections TO 10.10.10.10 are not. However, the system is permitted to send back information over SSH as long as the session has already been established, which makes SSH communication possible between these two hosts.

iptables -A INPUT -p tcp --dport ssh -s 10.10.10.10 -m state --state NEW,ESTABLISHED -j ACCEPT

iptables -A OUTPUT -p tcp --sport 22 -d 10.10.10.10 -m state --state ESTABLISHED -j ACCEPT

Saving Changes

The changes that you make to your iptables rules will be scrapped the next time that the iptables service gets restarted unless you execute a command to save the changes.  This command can differ depending on your distribution:

Ubuntu:

sudo /sbin/iptables-save

Red Hat / CentOS:

/sbin/service iptables save

Or

/etc/init.d/iptables save

Other Commands

List the currently configured iptables rules:

iptables -L

Adding the -v option will give you packet and byte information, and adding -n will list everything numerically. In other words – hostnames, protocols, and networks are listed as numbers.

To clear all the currently configured rules, you can issue the flush command.

iptables -F

original source : http://www.howtogeek.com/177621/the-beginners-guide-to-iptables-the-linux-firewall/

About iptables

iptables is a command-line firewall utility that uses policy chains to allow or block traffic. When a connection tries to establish itself on your system, iptables looks for a rule in its list to match it to. If it doesn’t find one, it resorts to the default action.

iptables almost always comes pre-installed on any Linux distribution. To update/install it, just retrieve the iptables package:

sudo apt-get install iptables

There are GUI alternatives to iptables like Firestarter, but iptables isn’t really that hard once you have a few commands down. You want to be extremely careful when configuring iptables rules, particularly if you’re SSH’d into a server, because one wrong command can permanently lock you out until it’s manually fixed at the physical machine.

Types of Chains

iptables uses three different chains: input, forward, and output.

Input – This chain is used to control the behavior for incoming connections. For example, if a user attempts to SSH into your PC/server, iptables will attempt to match the IP address and port to a rule in the input chain.

Forward – This chain is used for incoming connections that aren’t actually being delivered locally. Think of a router – data is always being sent to it but rarely actually destined for the router itself; the data is just forwarded to its target. Unless you’re doing some kind of routing, NATing, or something else on your system that requires forwarding, you won’t even use this chain.

There’s one sure-fire way to check whether or not your system uses/needs the forward chain.

iptables -L -v

The screenshot above is of a server that’s been running for a few weeks and has no restrictions on incoming or outgoing connections. As you can see, the input chain has processed 11GB of packets and the output chain has processed 17GB. The forward chain, on the other hand, has not needed to process a single packet. This is because the server isn’t doing any kind of forwarding or being used as a pass-through device.

Output – This chain is used for outgoing connections. For example, if you try to ping howtogeek.com, iptables will check its output chain to see what the rules are regarding ping and howtogeek.com before making a decision to allow or deny the connection attempt.

The caveat

Even though pinging an external host seems like something that would only need to traverse the output chain, keep in mind that to return the data, the input chain will be used as well. When using iptables to lock down your system, remember that a lot of protocols will require two-way communication, so both the input and output chains will need to be configured properly. SSH is a common protocol that people forget to allow on both chains.

Policy Chain Default Behavior

Before going in and configuring specific rules, you’ll want to decide what you want the default behavior of the three chains to be. In other words, what do you want iptables to do if the connection doesn’t match any existing rules?

To see what your policy chains are currently configured to do with unmatched traffic, run theiptables -L command.

As you can see, we also used the grep command to give us cleaner output. In that screenshot, our chains are currently figured to accept traffic.

More times than not, you’ll want your system to accept connections by default. Unless you’ve changed the policy chain rules previously, this setting should already be configured. Either way, here’s the command to accept connections by default:

iptables --policy INPUT ACCEPT
iptables --policy OUTPUT ACCEPT
iptables --policy FORWARD ACCEPT

By defaulting to the accept rule, you can then use iptables to deny specific IP addresses or port numbers, while continuing to accept all other connections. We’ll get to those commands in a minute.

If you would rather deny all connections and manually specify which ones you want to allow to connect, you should change the default policy of your chains to drop. Doing this would probably only be useful for servers that contain sensitive information and only ever have the same IP addresses connect to them.

iptables --policy INPUT DROP
iptables --policy OUTPUT DROP
iptables --policy FORWARD DROP

Connection-specific Responses

With your default chain policies configured, you can start adding rules to iptables so it knows what to do when it encounters a connection from or to a particular IP address or port. In this guide, we’re going to go over the three most basic and commonly used “responses”.

Accept – Allow the connection.

Drop – Drop the connection, act like it never happened. This is best if you don’t want the source to realize your system exists.

Reject – Don’t allow the connection, but send back an error. This is best if you don’t want a particular source to connect to your system, but you want them to know that your firewall blocked them.

The best way to show the difference between these three rules is to show what it looks like when a PC tries to ping a Linux machine with iptables configured for each one of these settings.

Allowing the connection:

Dropping the connection:

Rejecting the connection:

Allowing or Blocking Specific Connections

With your policy chains configured, you can now configure iptables to allow or block specific addresses, address ranges, and ports. In these examples, we’ll set the connections to DROP, but you can switch them to ACCEPT or REJECT, depending on your needs and how you configured your policy chains.

Note: In these examples, we’re going to use iptables -A to append rules to the existing chain. iptables starts at the top of its list and goes through each rule until it finds one that it matches. If you need to insert a rule above another, you can use iptables -I [chain] [number] to specify the number it should be in the list.

Connections from a single IP address

This example shows how to block all connections from the IP address 10.10.10.10.

iptables -A INPUT -s 10.10.10.10 -j DROP

Connections from a range of IP addresses

This example shows how to block all of the IP addresses in the 10.10.10.0/24 network range. You can use a netmask or standard slash notation to specify the range of IP addresses.

iptables -A INPUT -s 10.10.10.0/24 -j DROP

or

iptables -A INPUT -s 10.10.10.0/255.255.255.0 -j DROP

Connections to a specific port

This example shows how to block SSH connections from 10.10.10.10.

iptables -A INPUT -p tcp --dport ssh -s 10.10.10.10 -j DROP

You can replace “ssh” with any protocol or port number. The -p tcp part of the code tells iptables what kind of connection the protocol uses.  If you were blocking a protocol that uses UDP rather than TCP, then -p udp would be necessary instead.

This example shows how to block SSH connections from any IP address.

iptables -A INPUT -p tcp --dport ssh -j DROP

Connection States

As we mentioned earlier, a lot of protocols are going to require two-way communication. For example, if you want to allow SSH connections to your system, the input and output chains are going to need a rule added to them. But, what if you only want SSH coming into your system to be allowed? Won’t adding a rule to the output chain also allow outgoing SSH attempts?

That’s where connection states come in, which give you the capability you’d need to allow two way communication but only allow one way connections to be established. Take a look at this example, where SSH connections FROM 10.10.10.10 are permitted, but SSH connections TO 10.10.10.10 are not. However, the system is permitted to send back information over SSH as long as the session has already been established, which makes SSH communication possible between these two hosts.

iptables -A INPUT -p tcp --dport ssh -s 10.10.10.10 -m state --state NEW,ESTABLISHED -j ACCEPT

iptables -A OUTPUT -p tcp --sport 22 -d 10.10.10.10 -m state --state ESTABLISHED -j ACCEPT

Saving Changes

The changes that you make to your iptables rules will be scrapped the next time that the iptables service gets restarted unless you execute a command to save the changes.  This command can differ depending on your distribution:

Ubuntu:

sudo /sbin/iptables-save

Red Hat / CentOS:

/sbin/service iptables save

Or

/etc/init.d/iptables save

Other Commands

List the currently configured iptables rules:

iptables -L

Adding the -v option will give you packet and byte information, and adding -n will list everything numerically. In other words – hostnames, protocols, and networks are listed as numbers.

To clear all the currently configured rules, you can issue the flush command.

iptables -F

original source : http://www.pbxer.com/asterisk-security-use-iptables-to-block-nasty-hosts/

ASTERISK SECURITY: USE IPTABLES TO BLOCK THE BAD GUYS

Having your asterisk server on the public internet, people will try to use your phone system for free.

One technique is for scripts simply to look for any accounts with easy to guess usernames and passwords. It’s easy to spot these attempts in the log files. Just look for any “Fail” messages:

grep “Fail” /var/log/asterisk/messages

[Jun 18 07:42:15] NOTICE[31682] chan_sip.c: Failed to authenticate user "MeucciSolutions" ;tag=as6f2c0dfb[Jun 18 07:49:45] NOTICE[31682] chan_sip.c: Failed to authenticate user "MeucciSolutions" ;tag=as51af5dba
[Jun 18 09:02:47] NOTICE[31682] chan_sip.c: Failed to authenticate user "MeucciSolutions" ;tag=as3c4e5e5b
[Jun 18 09:57:09] NOTICE[31682] chan_sip.c: Failed to authenticate user "MeucciSolutions" ;tag=as22d69494
...

As you can see, some joker at 74.55.157.130 tried several times to authenticate on my server. Now, I have passwords that are not easy to guess, but still I’d prefer to block them from even getting to my asterisk server. Linux has a built-in firewall and it is possible to simply reject any packets from this IP address.

iptables -I INPUT -s 74.55.157.130 -j DROP

That translates to: If any packets come from this particular IP address (source), ignore (drop) them.

To view (list) all the blocked IP addresses:

iptables -n -L

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
DROP       all  --  74.55.157.130        0.0.0.0/0

original source : http://www.pbxer.com/asterisk-security-use-iptables-to-block-nasty-hosts/

ASTERISK SECURITY: USE IPTABLES TO BLOCK THE BAD GUYS

Having your asterisk server on the public internet, people will try to use your phone system for free.

One technique is for scripts simply to look for any accounts with easy to guess usernames and passwords. It’s easy to spot these attempts in the log files. Just look for any “Fail” messages:

grep “Fail” /var/log/asterisk/messages

[Jun 18 07:42:15] NOTICE[31682] chan_sip.c: Failed to authenticate user "MeucciSolutions" ;tag=as6f2c0dfb[Jun 18 07:49:45] NOTICE[31682] chan_sip.c: Failed to authenticate user "MeucciSolutions" ;tag=as51af5dba
[Jun 18 09:02:47] NOTICE[31682] chan_sip.c: Failed to authenticate user "MeucciSolutions" ;tag=as3c4e5e5b
[Jun 18 09:57:09] NOTICE[31682] chan_sip.c: Failed to authenticate user "MeucciSolutions" ;tag=as22d69494
...

As you can see, some joker at 74.55.157.130 tried several times to authenticate on my server. Now, I have passwords that are not easy to guess, but still I’d prefer to block them from even getting to my asterisk server. Linux has a built-in firewall and it is possible to simply reject any packets from this IP address.

iptables -I INPUT -s 74.55.157.130 -j DROP

That translates to: If any packets come from this particular IP address (source), ignore (drop) them.

To view (list) all the blocked IP addresses:

iptables -n -L

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
DROP       all  --  74.55.157.130        0.0.0.0/0

inline-block is something I hadn’t used until a couple of months ago. I was comfortable with block and inline elements so I didn’t feel the need to learn anything more. I was also under the impression, as I’m sure many developers are, that anything other than display: blockand display: inline has cross-browser inconsistency problems and should be avoided.

This article focuses on why you should start using display: inline-block, understanding this value as well as how to make sure it is consistent across all modern browsers and IE7+.

Note: If you don’t yet know the differences between inline and block level elements, check out what css-101 has to say about it.

inline-block is your missing friend

inline-block solves all sorts of problems web-devs run into on a daily basis. I’m going to go through various common scenarios and cover how I would deal with them in a cross-browser fashion. You may notice some odd/hacky CSS included in the following examples – this will be covered in the Browser Compatibility section later in the article.

inline-block vertically center (IBVC) hack

Chris Coyier talks about a “Ghost” IBVC method and he credits Michal Czernow for it’s origin. Chris also mentions how it’s equivalent to the display: table/table-cell method since it also doesn’t support IE7. I’ve been playing around with inline-block and tinkering with vertical centering and I’ve come up with something that seems to be the ‘Ghost’ method (I’d discovered the ‘Ghost’ method after stumbling upon this solution) with a few differences. The two differences being mine supports IE6+ (not that IE6 matters at all anymore, just an FYI) and it doesn’t require pseudo elements to function.

Being able to vertically center an element with a dynamic height is something that has plagued developers (or me at least) for a very long time and the cross-browser solution has been somewhat of a holy grail. I’ve seen many different vertical centering methods, the most popular being the display: table used with display: table-cell. The problem with this is IE7 doesn’t support either of those display values.

I feel this hack is a more simple and easily understandable way of vertically/horizontally centering an element than the previously mentioned table/table-cell/IE7-bug-hack method. I also feel it’s much easier to understand and work with than the Gary Turner method too, but well done to him for coming up with that over 7 years ago. I’m sure other people will feel differently about this being the “best” way, however this is what I prefer..

Problems

vertical-align property

One slight downside to this I’ve noticed is vertical-align: middle vertically aligns the capital letters, so lower case letters or inline-block elements are very slightly off center. I’ve noticed elements being off by about 2px to 4px depending on what size the items are. Although this occurs it’s pretty much negligible for me – especially since I can’t actually notice this unless I actually count pixels.

Space characters

Space characters are handled like a space would be handled within inline-elements. This means that spaces and or tabs will be displayed as a space once the page has rendered. There are a couple of ways to work around this problem but it can be annoying nonetheless.

IE7 hand-holding

The above mentioned ‘space characters’ problem doesn’t take affect in IE7. The problem IE7 does come with is that it requires at least 1 other inline-block element to be present to allow the inline-block to vertically center. To get around this, I’ve added an “invisible” element after the item I’m centering – I’ve added it afterwards incase :first-child is used. This was included in the Ghost method through pseudo elements. Even though I’ve managed to remove pseudo elements, I’ve had to add an equivalent (or worse since it’s actual markup) for IE7. Boo.

Alternative methods

There is an IE7 CSS bug in which you can center an element vertically, and if used along side the table/table-cell method, it can work nicely (However I haven’t used it in practice). This can also be done using the Flexbox layout module – Flexbox is definitely something that will be used much more in future, however as Le Roux pointed out to me, the current Flexbox support right now is a bit flakey – So it may be another 1 or 2 years before we can start using it with absolute confidence.

Centering navigation items

I often come across a navigation design where the amount of items in the navigation should be dynamic, however the navigation itself should remain centered regardless of how many or how wide the items are. Previously I would have centered this with display: table, however, since display: table doesn’t have any IE7 support, I would have probably also used an IE7 javascript fallback (Or just let the navigation appear left aligned in IE7). With display: inline-block, this same result can be achieved with 2 (or 4 including IE7 support) css properties and values.

How simple was that? Seriously?

Article block listings

Generally I solve the following kind of problem differently depending on the exact design and how I feel at the time.

article listing example

An easy inline-block solution would be:

The design could have been more tricky, though. Typically the height would be dynamic, or possibly both the height and width. As you can see this isn’t exactly a masonry layout since each row starts and ends at the same top-offset. It is still not possible to solve a masonry design in LTE IE9 without javascript. The height of these items are dynamic though, mere floats wouldn’t work correctly. If we used floats would end up with something like this:

To avoid that we could use :nth-child and detect the first item in each row and then clear: left, but that would pose some cross-browser problems itself since :nth-child is only supported by modern browsers. We could add classes to these items via the CMS/backend language, but it would be easier if we could just get this working with CSS alone and without any problems! :(
Yay, inline-block the the rescue again! :D You didn’t expect that did you?!

More navigation

Surely there is some limit to the IE7 support? What about an inline-block within an inline-block?!

In the above example I have 3 levels of nested inline-block items and it works perfectly in IE7+.

Browser compatibility

If you’ve read up until this point, you are well aware that an IE7 hack should be used to “enable” the inline-block functionality.

The IE7 hack

.item { display: block; *display: inline; zoom: 1; }

This could be turned into valid CSS if you are using the <html> conditional classes (included in h5bp):

.item { display: inline-block; }
.lt-ie8 .item { display: inline; zoom: 1; }

Why does that work?

IE7 doesn’t support inline-block per se, however you can mimic the functionality by making it be an inline element and triggering hasLayout on the element. The zoom: 1 visually doesn’t change anything. It is applied this way because it is one of the properties that triggers hasLayout.

Conclusion

inline-block is an amazing and underrated and underused property, in my opinion. inline-block is something that can and should be used today with confidence. We fear that which we do not understand – hopefully inline-block is now added to your CSS toolbox.

inline-block is something I hadn’t used until a couple of months ago. I was comfortable with block and inline elements so I didn’t feel the need to learn anything more. I was also under the impression, as I’m sure many developers are, that anything other than display: blockand display: inline has cross-browser inconsistency problems and should be avoided.

This article focuses on why you should start using display: inline-block, understanding this value as well as how to make sure it is consistent across all modern browsers and IE7+.

Note: If you don’t yet know the differences between inline and block level elements, check out what css-101 has to say about it.

inline-block is your missing friend

inline-block solves all sorts of problems web-devs run into on a daily basis. I’m going to go through various common scenarios and cover how I would deal with them in a cross-browser fashion. You may notice some odd/hacky CSS included in the following examples – this will be covered in the Browser Compatibility section later in the article.

inline-block vertically center (IBVC) hack

Chris Coyier talks about a “Ghost” IBVC method and he credits Michal Czernow for it’s origin. Chris also mentions how it’s equivalent to the display: table/table-cell method since it also doesn’t support IE7. I’ve been playing around with inline-block and tinkering with vertical centering and I’ve come up with something that seems to be the ‘Ghost’ method (I’d discovered the ‘Ghost’ method after stumbling upon this solution) with a few differences. The two differences being mine supports IE6+ (not that IE6 matters at all anymore, just an FYI) and it doesn’t require pseudo elements to function.

Being able to vertically center an element with a dynamic height is something that has plagued developers (or me at least) for a very long time and the cross-browser solution has been somewhat of a holy grail. I’ve seen many different vertical centering methods, the most popular being the display: table used with display: table-cell. The problem with this is IE7 doesn’t support either of those display values.

I feel this hack is a more simple and easily understandable way of vertically/horizontally centering an element than the previously mentioned table/table-cell/IE7-bug-hack method. I also feel it’s much easier to understand and work with than the Gary Turner method too, but well done to him for coming up with that over 7 years ago. I’m sure other people will feel differently about this being the “best” way, however this is what I prefer..

Problems

vertical-align property

One slight downside to this I’ve noticed is vertical-align: middle vertically aligns the capital letters, so lower case letters or inline-block elements are very slightly off center. I’ve noticed elements being off by about 2px to 4px depending on what size the items are. Although this occurs it’s pretty much negligible for me – especially since I can’t actually notice this unless I actually count pixels.

Space characters

Space characters are handled like a space would be handled within inline-elements. This means that spaces and or tabs will be displayed as a space once the page has rendered. There are a couple of ways to work around this problem but it can be annoying nonetheless.

IE7 hand-holding

The above mentioned ‘space characters’ problem doesn’t take affect in IE7. The problem IE7 does come with is that it requires at least 1 other inline-block element to be present to allow the inline-block to vertically center. To get around this, I’ve added an “invisible” element after the item I’m centering – I’ve added it afterwards incase :first-child is used. This was included in the Ghost method through pseudo elements. Even though I’ve managed to remove pseudo elements, I’ve had to add an equivalent (or worse since it’s actual markup) for IE7. Boo.

Alternative methods

There is an IE7 CSS bug in which you can center an element vertically, and if used along side the table/table-cell method, it can work nicely (However I haven’t used it in practice). This can also be done using the Flexbox layout module – Flexbox is definitely something that will be used much more in future, however as Le Roux pointed out to me, the current Flexbox support right now is a bit flakey – So it may be another 1 or 2 years before we can start using it with absolute confidence.

Centering navigation items

I often come across a navigation design where the amount of items in the navigation should be dynamic, however the navigation itself should remain centered regardless of how many or how wide the items are. Previously I would have centered this with display: table, however, since display: table doesn’t have any IE7 support, I would have probably also used an IE7 javascript fallback (Or just let the navigation appear left aligned in IE7). With display: inline-block, this same result can be achieved with 2 (or 4 including IE7 support) css properties and values.

How simple was that? Seriously?

Article block listings

Generally I solve the following kind of problem differently depending on the exact design and how I feel at the time.

article listing example

An easy inline-block solution would be:

The design could have been more tricky, though. Typically the height would be dynamic, or possibly both the height and width. As you can see this isn’t exactly a masonry layout since each row starts and ends at the same top-offset. It is still not possible to solve a masonry design in LTE IE9 without javascript. The height of these items are dynamic though, mere floats wouldn’t work correctly. If we used floats would end up with something like this:

To avoid that we could use :nth-child and detect the first item in each row and then clear: left, but that would pose some cross-browser problems itself since :nth-child is only supported by modern browsers. We could add classes to these items via the CMS/backend language, but it would be easier if we could just get this working with CSS alone and without any problems! :(
Yay, inline-block the the rescue again! :D You didn’t expect that did you?!

More navigation

Surely there is some limit to the IE7 support? What about an inline-block within an inline-block?!

In the above example I have 3 levels of nested inline-block items and it works perfectly in IE7+.

Browser compatibility

If you’ve read up until this point, you are well aware that an IE7 hack should be used to “enable” the inline-block functionality.

The IE7 hack

.item { display: block; *display: inline; zoom: 1; }

This could be turned into valid CSS if you are using the <html> conditional classes (included in h5bp):

.item { display: inline-block; }
.lt-ie8 .item { display: inline; zoom: 1; }

Why does that work?

IE7 doesn’t support inline-block per se, however you can mimic the functionality by making it be an inline element and triggering hasLayout on the element. The zoom: 1 visually doesn’t change anything. It is applied this way because it is one of the properties that triggers hasLayout.

Conclusion

inline-block is an amazing and underrated and underused property, in my opinion. inline-block is something that can and should be used today with confidence. We fear that which we do not understand – hopefully inline-block is now added to your CSS toolbox.