A
FAQ on various IRC channels I help out on is
How do I vertically center my stuff inside this area?
This question is often followed by
I'm using vertical-align:middle but it's not working!
The problem here is three-fold:
- HTML layout traditionally was not designed to specify vertical behavior. By its very nature, it scales width-wise, and the content flows to an appropriate height based on the available width. Traditionally, horizontal sizing and layout is easy; vertical sizing and layout was derived from that.
- The reason
vertical-align:middle isn't doing what is desired want is because the author doesn't understand what it's supposed to do, but …
- … this is because the CSS specification really screwed this one up (in my opinion)—
vertical-align is used to specify two completely different behaviors depending on where it is used.
vertical-align in table cells
When used in table cells,
vertical-align does what most people expect it to, which is mimic the (old, deprecated)
valign attribute. In a modern, standards-compliant browser, the following three code snippets do the same thing:
<td valign="middle"> <!-- but you shouldn't ever use valign --> </td>
<td style="vertical-align:middle"> ... </td>
<div style="display:table-cell; vertical-align:middle"> ... </div>
Shown in your browser, the above (with appropriate wrappers) display as:
<td> using valign="middle" |
<td> using valign="bottom" |
<td> using vertical-align:middle |
<td> using vertical-align:bottom |
<div> using display:table-cell; vertical-align:middle
<div> using display:table-cell; vertical-align:bottom
vertical-align on inline elements
When
vertical-align is applied to inline elements, however, it's a whole new ballgame. In this situation, it behaves like the (old, deprecated)
align attribute did on
<img> elements. In a modern, standards-compliant browser, the following three code snippets do the same thing:
<img align="middle" ...>
<img style="vertical-align:middle" ...>
<span style="display:inline-block; vertical-align:middle"> foo<br>bar </span>
In your browser, here's how the above code renders:
In this paragraph, I have two images—

and

—as examples.
In this paragraph, I have two images—

and

—as examples.
In this paragraph, I have a cute little
<span> display:inline-block
vertical-align:middle and
display:inline-block
vertical-align:text-bottom as an example.
vertical-align on other elements
Technically, this CSS attribute doesn't go on any other kinds of elements. When the novice developer applies
vertical-align to normal block elements (like a standard
<div>) most browsers set the value to inherit to all inline children of that element.
So how do I vertically-center something?!
If you are reading this page, you're probably not as interested in why what you were doing is wrong. You probably want to know how to do it properly.
Method 1
The following example makes two (non-trivial) assumptions. If you can meet these assumptions, then this method is for you:
- You can put the content that you want to center inside a block and specify a fixed height for that inner content block.
- It's alright to absolutely-position this content. (Usually fine, since the parent element inside which the content is centered can still be in flow.
If you can accept the above necessities, the solution is:
- Specify the parent container as
position:relative or position:absolute.
- Specify a fixed height on the child container.
- Set
position:absolute and top:50% on the child container to move the top down to the middle of the parent.
- Set
margin-top:-yy where yy is half the height of the child container to offset the item up.
An example of this in code:
<style type="text/css">
#myoutercontainer { position:relative }
#myinnercontainer { position:absolute; top:50%; height:10em; margin-top:-5em }
</style>
...
<div id="myoutercontainer">
<div id="myinnercontainer">
<p>Hey look! I'm vertically centered!</p>
<p>How sweet is this?!</p>
</div>
</div>
In your browser, the above example renders as:
Hey look! I'm vertically centered!
How sweet is this?!
Method 2
This method requires that you be able to satisfy the following conditions:
- You have only a single line of text that you want to center.
- You can specify a fixed-height for the parent element.
If you can accept the above necessities, the solution is:
- Set the
line-height of the parent element to the fixed height you want.
An example of this in code:
<style type="text/css">
#myoutercontainer2 { line-height:4em }
</style>
...
<p id="myoutercontainer2">
Hey, this is vertically centered. Yay!
</p>
In your browser, the above example renders as:
Hey, this is vertically centered. Yay!
82 Responses
Anyway, you are absolutely correct..
I meant 301, said 301, and have no idea why I wrote 302 in the code (could be all the pain meds?).. either way, thank you for catching the error. The code now reads correctly (i think)..
# block IP range by CIDR numberorder allow,denyallow from alldeny from 214.53.25.64/26# block an IP range via network/netmask valuesorder allow,denyallow from alldeny from 214.53.25.64/255.255.255.192RewriteEngine OnRewriteCond %{REMOTE_ADDR} ^214\.53\.25\.(6[4-9]|7[0-9]|8[0-9]|9[0-9])$ [OR]RewriteCond %{REMOTE_ADDR} ^214\.53\.25\.1([0-1][0-9]|2[0-8])$RewriteRule .* - [F]# permanently redirect multiple IP requests for single pageRewriteEngine OnRewriteBase /RewriteCond %{REMOTE_HOST} 123\.456\.789RewriteCond %{REMOTE_HOST} 456\.789\.123RewriteCond %{REMOTE_HOST} 789\.123\.456RewriteCond %{REQUEST_URI} /requested-page\.html$RewriteRule .* /just-for-you.html [R=301,L]##-###-##-###.dhcp.insightbb.com
Order Allow,DenyAllow from allDeny from dhcp.insightbb.comHere is another way of blocking a specific ISP via its IP address(es).
Order Allow,DenyAllow from allDeny from 123.123.123.Deny from 456.456.456.I am novice enough that I don’t know for sure that I know where to put this code or which part of it I need - and need to edit.
I apologize for being high maintenance about this - but any help you could offer would be greatly appreciated. Please do not comment ON my blog about this issue for the above stated reasons!
What I would like to do is block his ranges of IPs and refer him to a “You are not welcome” page. I’m not IP savvy so would it be best to block him based on the first 2 octets or be more specific and do it on 3? If it means blocking a handful of innocent visitors in his area, so be it - I just cant stand the continued abuse anymore.
Also, what would the code be to do it?
I’m sorry for the longwinded message but I’m at my wits end!
user@host:~$ dig +short perishablepress.com207.210.105.30user@host:~$ whois 207.210.105.30[examine output, looking for “netrange”, “cidr”, “inetnum”, or anything else that means “more than one IP”]
user@host:~$ whois 207.210.105.30 | grep -i cidrCIDR: 207.210.64.0/18[debian unstable or ubuntu gutsy or hardy:
sudo apt-get install libnetaddr-ip-perl;redhat: have fun with that …]user@host:~$ cat bin/netblock2regex#!/usr/bin/perluse NetAddr::IP;my $ip = new NetAddr::IP $ARGV[0], $ARGV[1];print $ip->re(), "\n";user@host:~$ ./bin/netblock2regex 207.210.64.0 18?:(?78|79|80|81|82|83|84|85|86|87|88|89|90|91|92|93|94|95|96|97|98|99|100|101|102|103|104|105|106|107|108|109|110|111|112|113|114|115|116|117|118|119|120|121|122|123|124|125|126|127)\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?![0-9]))123.\123\.123” in your htaccess file. Everything else stays the same.Jonathan
# block ISP by CIDROrder Allow,DenyAllow from allDeny from 207.210.64.0/18Jeff
Great article. I have one question though: How do I redirect a page that is being served up by Wordpress’ rewrite rule?
# RewriteEngine On# RewriteBase /# RewriteCond %{REMOTE_HOST} xxx\.xxx\.xxx# RewriteCond %{REQUEST_URI} ./wordpress/page-to-block\.php$# RewriteRule ./wordpress/page-to-redirect.php [R=301,L]\.php) from the second rewrite condition. Also, in the rewrite rule itself, you could try adding a string to match against, for example:RewriteRule (.*) http://domain.tld/target-file.php [R=301,L]No, unfortunately the redirect method described in the article is a server-side technique that requires server access to implement. I think MySpace recently restricted server access to staff only, sadly..
mod_rewriteis not the optimal way of identifying IP addresses, but it is needed to accomplish the URL-specific redirect. Perhaps there is another issue involved..?mysite.com/index.php?option=com_jdownloads&Itemid=49&task=viewcategory&catid=9mysite.com/index.php?option=com_jdownloads&Itemid=49&task=viewcategory&catid=7%{REQUEST_URI}%{QUERY_STRING}variable.RewriteCond %{QUERY_STRING} target\-string\-01 [NC,OR]RewriteCond %{QUERY_STRING} target\-string\-02 [NC]RewriteRule .* - [F,L]# permanently redirect specific IP request for single pageRewriteEngine OnRewriteBase /RewriteCond %{REMOTE_HOST} 123\.456\.789RewriteCond %{REQUEST_URI} /requested-page\.html$RewriteRule .* /just-for-you.html [R=301,L]RewriteCondand get the desired results. You may also want to check out this technique, which requires a password for any specified IPs, allowing open access to everyone else.allow from all
RewriteEngine OnRewriteBase /RewriteRule .* /just-for-you.html [R=301,L]RewriteCond %{REQUEST_URI} /requested-page\.html$RewriteEngine OnRewriteBase /RewriteCond %{REMOTE_HOST} 123\.456\.789RewriteCond %{REQUEST_URI} /requested-page\.html$RewriteRule .* /just-for-you.html [R=301,L]^/$Redirect 301 /images/directory/ http://site.com/gallery/index.phpRedirect 301 /images/subdir/ /images/index.phpRewriteEngine OnRewriteBase /RewriteCond %{REQUEST_URI} /images/dir/$RewriteRule .* /images/index.php [R=301,L]This is not the case. The rule I posted above only works on the directory name, hence excluding the actual file from the rewrite.
www.mywebsite.comfrom affiliate links, from the rest of the traffic, and send them to different pages. As Clickbank passes the affiliate’s nickname to the vendor in a parameter called “hop”, I would like all page requests containing parameter “hop” (*/?hop=) to be directed towww.mywebsite.com/index.htmlwhere customers can pay using Clickbank gateway, making my affiliates happy, whereas redirect all the remaining traffic towww.mywebsite.com/index2.htmlwhere a different payment processor is set up.Is this something that can be done to .htaccess? If so, how?
I would be eternally grateful for any help.
QUERY_STRINGparameter. Use something like:RewriteCond %{QUERY_STRING} hop [NC]RewriteRule (.*) http://www.mywebsite.com/index.html [R=301,L]hop” go toindex.htmlby default.http://www.mywebsite.com/?hop=affiliatename is directed to index.html. What I have no idea about is how to redirect the rest of the hop-less traffic toindex2.html…hop”, we can target query strings that don’t contain it by using a “not” operator (exclamation point) before the target string:RewriteCond %{QUERY_STRING} !hop [NC]RewriteRule (.*) http://www.mywebsite.com/index2.html [R=301,L]hopin the query string and redirect it to the alternate index page.Firefox has detected that the server is redirecting the request for this address in a way that will never complete.<<
index2.htmlafter 15 minutes of loading. The page is displayed without formatting, pictures, etc. but at least it’s there.RewriteCond %{REQUEST_URI} !/index2.html$The script is working flawlessly now! I’m so relieved!
RewriteEngine onRewriteBase /RewriteCond %{REMOTE_HOST} 111.222.0.0/9RewriteCond %{REMOTE_HOST} 333.444.0.0/9RewriteCond %{REMOTE_HOST} 555.666.0.0/9RewriteCond %{REMOTE_HOST} 777.888.99.10RewriteCond %{REQUEST_URI} ^/$RewriteRule .* /default.html [R=301,L][OR]flags at the end of the appropriate conditions. Something like this:RewriteCond %{REMOTE_HOST} 111.222.0.0/9 [OR]RewriteCond %{REMOTE_HOST} 333.444.0.0/9 [OR]RewriteCond %{REMOTE_HOST} 555.666.0.0/9 [OR]RewriteCond %{REMOTE_HOST} 777.888.99.10RewriteCond %{REQUEST_URI} ^/$RewriteRule .* /default.html [R=301,L][OR]flag are interpreted in additive fashion, which is why your code fails — it is impossible for any single host to be coming from multiple IPs.RewriteEngine onRewriteBase /RewriteCond %{REMOTE_HOST} 11.222.0.0/17 [OR]RewriteCond %{REMOTE_HOST} 44.55.64.0/19RewriteCond %{REQUEST_URI} ^/$RewriteRule .* /default.htm [R=301,L]Options +FollowSymLinksRewriteEngine OnRewriteBase /RewriteCond %{REMOTE_HOST} 127\.0\.0\.1RewriteRule .* /banned.htm [R=301,L]RewriteCond %{REQUEST_URI} "/functions/"RewriteRule (.*) $1 [L]RewriteRule ^([^.]+)/?$ /index.php?page=$1 [L]RewriteBaseto[R=301,L]and all of a sudden my banned page comes up.127.0.0.1the IP address for localhost (i.e., your server)? That would explain why it only works when you redirect to an external domain.[OR]variable for multiple IP addresses was getting me![OR]flag for multiple IPs. For others who may need help:# permanently redirect specific IP request for single pageRewriteEngine OnRewriteBase /RewriteCond %{REMOTE_HOST} 123\.456\.789 [OR]RewriteCond %{REMOTE_HOST} 456\.789\.123 [OR]RewriteCond %{REMOTE_HOST} 789\.123\.456RewriteCond %{REQUEST_URI} /requested-page\.html$RewriteRule .* /just-for-you.html [R=301,L][OR]flag on the last IP condition.order allow,denydeny from xx.xx.xx.x/xxallow from all/olddirectory/in access logs and when i check the error logs the bot is getting rejected and access is denied some times may be from the root directory./olddirectory/i am thinking if this script works out# permanently redirect specific IP request for entire siteOptions +FollowSymlinksRewriteEngine onRewriteCond %{REMOTE_HOST} 22\.22\.22\.239RewriteRule /olddirectory/ http://www.newsite.com/ [R=301,L]fixedname.variablename.ispname.com, and with that I can pretty confidently say all accesses fromfixedname.*.ispname.comis from this person. The ISP seems to divide the city into fixed blocks that I can tie the fixedname to this person’s location.RewriteCond %{REMOTE_HOST} fixedname.*.ispname.com?RewriteCond %{REMOTE_HOST} fixedname\.(.*)\.ispname\.com [NC]RewriteRule .* - [F]/So basically
www.mydomain.com/houseis a different site thanwww.mydomain.comThe site in the
/housefolder is both in Thai and in English, and I’m planning to use this script to redirect Thai IPs automatically to the Thai version, and all others to the English:RewriteCond %{REMOTE_HOST} 111.222.0.0/9 [OR]RewriteCond %{REMOTE_HOST} 333.444.0.0/9 [OR]RewriteCond %{REMOTE_HOST} 555.666.0.0/9 [OR]RewriteCond %{REQUEST_URI} ^/$RewriteRule .* /thai/ [R=301,L]/housesubdirectory, will it work? Or does such a file only work in the root directory?thaisubdirectory./house/directory, the redirect will go to/house/thai/directory. In other words, yes it should work in the subdirectory (instead of root), but the relative URI will be determined with the containing directory (i.e.,/house/) as root.tags, and someone will take a look at it..Thekla#76Thank you. Your help is greatly appreciated.RewriteEngine OnRewriteBase /RewriteCond %{REMOTE_HOST} xx\.xxx\.xxx\.xxxRewriteCond %{REQUEST_URI} /terridelights\.com$RewriteRule .* /stalkeralert.html[R=301,L]REMOTE_HOST, try withREMOTE_ADDR, and then also remove the secondRewriteCond:RewriteEngine OnRewriteCond %{REMOTE_ADDR} ^789\.123\.456\.3$RewriteRule .* http://terridelights.com/stalkeralert.html [R=301,L]RewriteRule. Here is more information onmod_rewriting using eight different variables.Firefox has detected that the server is redirecting the request for this address in a way that will never complete.
* This problem can sometimes be caused by disabling or refusing to accept
cookies.
RewriteEngine OnRewriteCond %{REMOTE_ADDR} ^789\.123\.456\.3$RewriteCond %{REQUEST_URI} !/stalkeralert.html$ [NC]RewriteRule .* http://terridelights.com/stalkeralert.html [R=301,L][OR]at the end of thesecondfirstRewriteCond..?