When centering things in html and css, I find two approaches - either applying on the element :
display:block;
margin:0 auto;
or using:
display:inline-block;
text-align:center; (on the parent element)
I always wonder which is better and why. Thanks!!
This is a classic and important question.
Elements can either be inline (meaning they all sit next to each other - like a span tag) or they can be block (meaning the stack up on top of each other - like a div tag).
Margin: auto, while a bit odd when you first see it, is the best and only way to center a block level (position static), element.
For anything that is display: inline (like a span tag) - the only way to center it is if you specify text-align: center on the parent. This will center everything display: inline inside it that is position: static;
Display: inline-block is a hybrid of the two that is relatively new (but supported as far back as ie7 if you use the hack mentioned in another answer). With inline-block, you get the benefits of inline, in that you can you stick a bunch of things next to each other and have them all be centered (think of a nav where all nav items are all centered), but ALSO have each item take advantage of some of the stuff you get with display: block - the most important one being HEIGHT.
Imagine a scenario where each nav item has a background image that is 80px tall - you can't make an inline element have a height of 80 - so you'd have to make each element display: block - only then can you give it a height. So to make them all appear next to each other, you'd float them. The problem is if you float them, you can't have them all be centered on the page unless you give a fixed width to the nav and margin: auto THAT. This means the nav has a fixed width - might be okay, but there are times when the nav has to have dynamic elements, different widths for different languages, etc.
Enter display: inline-block.
Block elements should always be centered using
.block {
margin-left: auto;
margin-right: auto;
width: 600px;
}
as stated by the w3c: http://www.w3.org/Style/Examples/007/center.en.html#block
text-align: center;
is well-named: use it to center texts.
Update
You can also use display: flex now:
.parent {
display: flex;
justify-content: center;
}
.block {
width: 200px;
}
There is no better way in this situation both approach will work and both are corrected. Just one thing display:inline-block doesn't work on IE7 (if you support this browser) you will need a hack to make it work
display: inline-block;
*display: inline;
zoom: 1;
Related
I am able to center horizontal list with text-align:center, but I wonder how can I keep it centered inside container, but has rows aligned left.
My container has percent width, so I need it working when resizing window and blocks are reordering
Please check the sample image below to understand my problem:
UPDATE:
Please find JsFiddle as per request
I need to center my <ul> inside div.container
Use this:
ul {
margin: auto;
}
li {
float: left;
}
See this fiddle:
You already know to center the <ul> with margin: auto;
The key is to adjust the <li> within it.
You can do that by using float: left;
Alternatively: you can set display: inline-block;
Both have a similar effect, but aren't identical. Play w/it.
By providing margins & percentage widths, you can play w/size and separation of the elements.
Since these are all block-level elements, they'll stack up & wrap automatically.
By floating or changing display of the <li> you keep them left-aligned within their parent element (the <ul>).
Also, by using separate CSS classes instead of targeting the <li> element directly, you leave things flexible in case you want to have a right-aligned list, or some other options later.
Wrap your boxes within another div.
You can then center that div with display: block; margin: 0 auto;, while keeping the boxes left-aligned.
I was trying to center text in two adjacent divs and I can not understand what I am doing wrong.
Basically I have 2 divs each taken 50% of the window. The first div contains an image (which I successfully centered) and I am trying to center the text in the second div. So here is my Fiddle and I am using the following css:
.thumbnail-descr{
text-align: center;
min-height: 10px;
display: table-cell;
vertical-align: middle;
font-size: 26pt;
color: #bbb;
}
There is no point of having original DOM structure or CSS (the main thing is to have 2 divs taking all the width and one has a centered image another one has a text. How can I achieve it?
What I understand from the example is that you want to vertically center "Descr". There are several tricks to do that:
Adjust the padding and use box-sizing border-box to have better control of the height.
Use flexbox (still not broadly available): https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Flexible_boxes
If you know before hand that you'll have only one line of text you can use line-height.
(See the update for another option)
For example see this Fiddle:
.square{
width: 45%;
height: 200px;
border: 3px dotted #ddd;
display:inline-block;
margin: 0 10px 0 10px;
line-height: 200px;
}
But take a few things into account:
This will work only if you have one line of text, because on text wrap it will be broken.
This is not the normal use of line height, it's taking advantage of a side effect: text is vertically centered to the line-height.
This trick is used by some CSS frameworks (ie Bootstrap) to center the text on some components.
Update
I forgot another option, since you have one div inside the other you can use position: relative on the parent, and use absolute position for the child using top: 50% and a negative top margin. You'll need to setup the top margin to the half of the child height. (that's how modals are usually centered):
.square { position: relative; /*..*/ }
.thumbnail-descr{
position: absolute;
top: 50%;
margin-top: -10px;
/*...*/
}
See http://jsfiddle.net/diegof79/M4fKM/1/
Also you asked why your solution is not working... this can help to understand the reasons: http://phrogz.net/css/vertical-align/index.html
Before proceeding to giving you the solution, you could have he exact same result with a lot less code, giving so many classes for so little content can only lead to huge code.
The span class you are giving the text-align:center, doesn't fill up the whole width of the parent, so, where would it center the text since its width is equal to the text?
You can either put a 'text-align:center" to the span's parent, the square class, but I would use a different approach in general.
Not sure if you need a span.
If you remove span tag and use same css for the div styles, or simply ad a span class name to a your div class name- works perfectly.
i think the issue happen because the width in the description div
Try this suggestion:
warp the with div, the div will use thumbnail-descr class
<div class='square'>
<div class="thumbnail-descr"><span>Descr</span><div>
</div>
Update the thumbnail-descr
.thumbnail-descr{
text-align: center;
min-height: 10px;
background-color:red;
vertical-align: middle;
font-size: 26pt;
color: #bbb;
width:100%;
}
hope this help
I am creating a simple site and I found out that I can center <img> tags with text-align: center; but id does not work on block elements like <div> for example. Can someone explain to me how exactly the text-align works and if it's god practice to use it to align images?
Thank you very much in advance :)
UPDATE
I also know about the margin: 0 auto; which in some situations works and in other situations it refuses to center elements.
It totally depends on your requirement, there are various ways to do so, one is that img is an inline element, so setting it to block and using margin: auto; will center your img
img {
display: block;
margin: auto;
}
Demo
Another way is which you are trying to attempt, which needs text-align: center; to be declared on the parent element and not the img tag itself, cuz I doubt you are using text-align: center; for the img tag and not for the parent... Where in the above solution we are targeting the img tag, so there's a difference between the two..
Demo
What's the good point here?
You don't have to make the img a block level element.
No need of margin: auto;
What's the bad point here?
If you have p elements inside the div, they will be centered aligned as well, because the align property is inherited.
Demo
So what to do now? Align the p elements to the left using text-align: left; property, and here we will be targetting p like
This will keep the image centered and will align the p to the left
.wrap {
text-align: center;
}
.wrap p {
text-align: left;
}
Demo
Last but not the least, we can also use CSS Positioning where you can have a parent element set to position: relative; and than we use position: absolute; for the img tag, and than we assign top: 50% and left: 50% and than we deduct the 1/2 of total height and width of your img by using margin-top and margin-left properties respectively. This method comes handy in case where you need the image vertically as well as horizontally centered. (This method will require fixed height and width to be declared)
<div>
<img src="img.png">
</div>
img {
display: block;
margin-left: auto;
margin-right: auto;
}
My advice is to use text-align property for the texts only (of course there could be exceptions). And for centering images you can simply do like this:
img{
display: block;
margin: 0 auto;
}
A 'div', or any block element, without a declared width, can't be centered with margin: 0 auto;, but images will. 'Auto' counts pixels for you and make an element appear in the center
See W3:
http://www.w3.org/TR/CSS21/text.html#alignment-prop
Whether you want to use margin:0 auto; or text-align:center , this really depends on what you're doing exactly and the surrounding markup, context.
I always try to use text-align:center; when possible. I also define images as a block which helps auto margins.
Also a great article by Chris at CSS tricks: http://css-tricks.com/centering-in-the-unknown/
The property text-algin:center basically does what it says. Its supposed to center text. You can either apply directly to the text that you want to center or apply it to the parent div. In this case every text within this div will be centered.
The better practise to center, e.g., images, is to use margin: 0 auto; as many have already suggested. Specifying auto tells the browser to automatically determine the left and right margins itself and to set them equal. It therefore guarantees that both margins have the same size, which is why the object is centered horizontally.
Hope that helps!
I have links and a sprite image I want to render in one line centered vertically:
HTML:
Why Eminem is the best
<div class="sprite" id="pointer"></div>
by
<img alt="Justin meltzer" src="/system/photos/1/tiny/Justin Meltzer.jpeg?1305874692">
Justin Meltzer
How would I get all of these elements on one line?
I'd do a jsfiddle but I don't have my sprite images at a public url
Set your div to display inline-block so that everything will stay on one line. Do you want the links to then be aligned with the center of the image?
http://jsfiddle.net/gUrc9/
div.sprite { background: blue; height: 50px; width: 50px; display: inline-block; }
UPDATE:
As pointed out in comments inline-block is not supported in IE6/7 unless the element it is applied to is naturally inline. So better solution would be to change div to span.
span.sprite { display: inline-block; }
Your going to need to set your pointer div to be displayed inline:
#pointer { display: inline;}
By default div tags are block-level elements. This will force them inline with the rest of the items.
I would start with one improvement. DIVs are displayed as block, so if u r using a sprite, u wud give it a width n height anyway, in that case go for SPAN.
Now wrap a div around them and give it a style:text-align: center;. Or you could also give this outer DIV a width. and do a margin: auto;.
You'd be better off using a <span> for the pointer - a <div> is for grouping related elements - which this doesn't. It will also sit on the same line automatically, becasue a span is an inline element.
I'm trying to put some (vertically-stacked) display:block elements within a display:inline-block element. According to the CSS specification, the inline-block element should be a containing block, so it can have display:block elements within it and those should not affect the rest of the layout.
However, the display:block elements inside the display:inline-block elements disrupt the rest of the page; so does having nothing at all within the inline-block, or even a basic element like a paragraph; only simple text avoids disruption of the rest of the page (by disruption I mean shifting other divs down, e.g. in this case the left red block moves down a line and has a blank white space above it). I'm using Firefox 3.0.6.
<html><head><style type="text/css">
#left {
display: inline-block;
background: red;
width: 20%;
height: 100%;
}
#right {
display: inline-block;
background: green;
width: 80%;
height: 100%;
}
</style></head><body>
<div id="left">Left</div><div id="right">Right</div>
</body></html>
The above shows as two panes, left red, right green, as expected. If I change "Right" to
<p>Right</p>
or remove it entirely, or (as I want to do) replace it with a couple of divs, I get the bad formatting.
Is this a Firefox bug, or am I doing something wrong, or are my expectations incorrect? (FWIW, IE 7 mangles them all equally, as if it doesn't understand inline-block; doesn't matter, this is an internal app. and I'm only using Firefox). I may be able to get the layout I want using float/margin, but I'd prefer not to have to do that.
Well display: inline-block can be a bit tricky to get cross-browser. It will require at minimum, a few hacks and, for Firefox 2, potentially an extra element.
CSS
.inlineBlock { display: -moz-inline-stack; display: inline-block; zoom: 1; *display: inline; }
display: -moz-inline-stack is for Firefox 2. All the immediate children will need to have display: block or otherwise be block level elements. Note if you need your inline-block element to shrink wrap I think you can use display: -moz-inline-box instead.
zoom: 1 gives hasLayout to the element (for IE 7 and below). Part 1 of the hack needed for IE7 and below compatibilty.
**display: inline* is a hack second part of the hack needed for IE7 and below compatibility.
I occasionally need to add overflow: hidden for IE compatibility as well.
For your specific situation i think what you need is:
<html><head><style type="text/css">
#left {
display: inline-block;
background: red;
width: 20%;
height: 100%;
vertical-align: top;
}
#right {
display: inline-block;
background: green;
width: 80%;
height: 100%;
vertical-align: top;
}
</style></head><body>
<div id="left">Left</div><div id="right"><p>Right</p><p>Right 2</p></div>
</body></html>
I get the bad formatting.
You are being bitten by margin collapsing, a CSS ‘cleverness’ which is a pain as often as it is a boon. The margin of the <p> collapses outwards to become a top margin on the inline-block; this then behaves as a margin would on an ‘inline’ element would, pushing the vertical-alignment of the text line out.
You can stop it happening by removing the margins from ‘p’ elements and using padding instead. Alternatively place a non-empty element with no top margin at the top of the block and one with no bottom margin at the bottom.
Is this a Firefox bug
I think possibly yes, according to the spec's:
Margins of inline-block elements do not collapse (not even with their in-flow children).
inline-block
This value causes an element to generate an inline-level block container. The inside of an inline-block is formatted as a block box, and the element itself is formatted as an atomic inline-level box.
visual rendering model