display: table property in older browsers - html

In order to vertically align dynamic text I use span tag with display: table-cell property. It's wrapped by div with display: table property, and it works like it should.
But problem is that doesn't work in older firefox versions. Unfortunately, I need support for firefox 7 and greater.
Is there simplier solution beside using of real html tables?

display:table-cell isn't the be all and end all of vertical alignment. Vertical alignment can still be easily achieved with CSS alone.
You'll need three things:
A containing divider with a specific height (fluid or static, it doesn't matter).
A relatively positioned "padding" divider with 50% height.
A container for the content you're wanting to vertically align.
You will need to know the exact height of your content container, however.
div#container {
height:500px;
}
div#paddingDivider {
height:50%;
}
div#contentContainer {
margin:0 auto; /* Centrally align the element */
height:100px; /* Declare the exact height of the element */
margin-top:-50px; /* Position half of the element inside the padding divider */
}
JSFiddle example.

According to the MDN reference for the display property, table display via CSS has been supported since Firefox version 1. You should be fine!

Related

How can I control the width of a <div> with display:table; with a <p> element inside with display:table-cell

I have a layout, where I have to make a vertical centeret, with a rotated text inside.
See fiddle: http://jsfiddle.net/C7mCc/3/
I use display:table; and display:table-cell; to make the vertical centering, which is working good.
The HTML
<div id="top-banner-advertising-text" class="v-center">
<p class="v-c-content">Annonce</p>
</div>
and the CSS
.v-center {
display: table;
}
.v-center .v-c-content {
display: table-cell;
vertical-align: middle;
}
But I only want the #top-banner-advertising-text to have a width of 15px. Like in this fiddle: http://jsfiddle.net/C7mCc/4/ where I have removed the .v-center and .v-c-content and therefore do not have the text vertical centered.
How can I control the width of the div?
This ended up being a lot more complicated than I expected. To control the width you must take into consideration your parent divs. There is an excellent explanation of this here:
100% height block with vertical text
Although this in order to help you out I went ahead and figured out how to switch this code up to swap the text to the other side of the img for you.
my jsfiddle:
http://jsfiddle.net/C7mCc/6/
To answer your questions, "How do I control the width".
This is done by taking the following lines in the css and making sure they match,
padding-left:2em; /* line-height of .wrapper div:first-child span */
width:2em; /* line-height of .wrapper div:first-child span */
height:2em; /* line-height of .wrapper div:first-child span */
line-height:2em; /* Copy to other locations */
Remember since your vertical now you must think about the padding left.
basically your line height padding left width and height come in to play.
We control them with em in order to make sure they are sized correctly.
Let me know if you need anymore help.
Sounds like you're looking for the not selector:
/* if it must not have the vertical centering class */
#top-banner-advertising-text:not(.v-center) {
width: 15px;
}
http://jsfiddle.net/C7mCc/5/
Alternately, you could leave the width as you have it in your 2nd example and add this:
#top-banner-advertising-text.v-center {
width: auto;
}
to set a width for an element displayed as table, you use : table-layout:fixed;
But you do not say that you want as well to rotate a text.
To rotate that text, you will need white-space:nowrap if more than one word (15px is really small).
to replace that text in middle, you will need translate(); and set that text in a container displayed as a table, so it expands over 15px and makes translate usable.
here an example with 2 version rotated 90 and -90 degres : http://codepen.io/gc-nomade/pen/JuAio.
For older IE, search for the old writing-mode http://msdn.microsoft.com/en-us/library/ie/ms531187%28v=vs.85%29.aspx ;) .

How to evenly space many inline-block elements?

Is it possible to evenly space many elements in a div with changeable width.
Here's not working example. If we use text-align:center; elements will be centered, but margin:0 auto; is not working. I want to accomplish something like justify+center:
|..<elem>..<elem>..<elem>..<elem>..| // for one container width
|..<elem>..<elem>..<elem>..| // for smaller container width
|....<elem>....<elem>....| // even smaller container
Container will be user resizable.
One picture is worth a 1000 words:
Container(red box) width:100%; So user can resize it (browser window, js, whatever).
<--> represent even spaces.
In second row <--> are bigger because there is more room. I was able to fake it with:
text-align:center;
word-spacing:3em; // but any fixed value looses proportion
I recently read about a very clever technique to do exactly what you're asking.
In short, you just need to use text-align:justify; on the container element to achieve this, in conjunction with an extra invisible block at the end.
This works because inline-block elements are seen as being part of the text content, each being effectively a single word.
Using justify will spread out the words in your text so that they fill the entire width of the element with extra space between the words. For inline-block elements, this means that they are spaced out with even spaces between them.
I mentioned an extra invisible block at the end. This is required because normal text-align:justify won't justify the last line of text. For normal text, that's exactly what you want, but for aligning inline-block boxes, you want them all to be aligned.
The solution is to add an extra invisible but 100% width element to the end of your list of inline-block elements. This will become effectively the last line of text, and thus the justify technique will work for the rest of your blocks.
You can use the :after pseudo-selector to create the invisible element without needing to modify your markup.
Here's an updated version of your jsFiddle to demonstrate: http://jsfiddle.net/ULQwf/298/
And here's the original article that explains it in more detail: http://www.barrelny.com/blog/text-align-justify-and-rwd/
[EDIT]
One final update after seeing the image you've added to the question. (I don't have a better answer, but some additional thoughts that might be useful).
Ideally what you need here is a :last-line selector. Then you could text-align:justify the main text and text-align:center the last line. That would do what you want.
Sadly, :last-line isn't a valid selector (:first-line is, but not :last-line), so that's the end of that idea.
A slightly more hopeful thought is text-align-last, which does exist as a feature. This could do exactly what you want:
text-align:justify;
text-align-last:center;
Perfect.
Except that it's non-standard and has very limited browser support.
You can read about here on MDN.
I guess as a last resort it might be an option for you, if you can live with only partial browser support. It would at least get what you want for some of your users. But that's not really a sensible way to go.
My gut feeling though is that this as as close as you're going to get. Tantalisingly close to what you want, but just not quite there. I hope I'm proved wrong, but I'll be surprised. Too bad though, because I it would seem like a perfectly logical thing to want to do.
I worked on your example, you have to make a combination of block / inline style since the justify alone just work for inline (text).
div{
width:530px; /* I changed the div size, because you a have fixed width otherwise you should use scrolling */
border:1px red solid;
text-align:justify; /* You will justify to 100$ of containing div, if you want to "center" just add another div with % size and centered */
}
div span{ /* I worked with your example you may use a class */
width:60px;
border:1px yellow solid;
display: inline-block; /* Inline-block */
position: relative; /* relative to container div*/
}
div:before{
content: ''; /* position for block element*/
display: block; /* the block part for the last item*/
width: 100%;
}
div:after {
content: '';
display: inline-block; /* inline-block for the first (and middle elements) */
width: 100%;
}
If tried a different approach, in the fiddle looks pretty similiar to the picture but the space is fixed in both lines but the elements are intercalated.
div{
width:250px; /* I changed the div size, because you a have fixed width otherwise you should use scrolling */
border:1px red solid;
text-align:center; /* You will justify to 100$ of containing div, if you want to "center" just add another div with % size and centered */
}
div span{ /* I worked with your example you may use a class */
width:60px;
float:justify;
border:1px yellow solid;
display: inline-block; /* Inline-block */
margin-left:2%;
margin-right:2%;
}

Make div fill remaining space of parent

I need some help with positioning divs. The HTML structure is as follows:
<div class="container">
<div class="item">
<div class="left">
lorem lorem
</div>
<div class="right">
<p>right</p>
<p class="bottom">bottom</p>
</div>
</div>
</div>
And I have the following CSS:
.container {
float: left;
padding: 15px;
width: 600px;
}
.item {
float: left;
padding: 15px;
width: 570px;
}
.left {
float: left;
padding: 40px 20px;
margin-right: 10px;
}
.right {
position: relative;
float: left;
}
.bottom {
position: absolute;
bottom: 0;
}
The width and height of the left div is dynamic.
What I want to achieve is:
Make the height of the right div equal to height of the left div.
Make the width of the right div fill the rest of the div with class item.
The paragraph with class bottom should be at the bottom of the right div.
Here is a simple image that represents my goal:
And a link to a JSFiddle demo.
Getting the correct position and width of .bottom appears to be the biggest hurdle for a cross-browser, CSS solution.
Options
1. Floats
As #joeellis demonstrated, the flexible widths can be achieved by floating only the left column, and applying overflow:hidden to the right column.
The position of .bottom cannot be achieved in any browser. There's no CSS solution for floated columns with equal, variable height. An absolutely positioned .bottom element must be inside the right column div, so that 100% width would give it the correct size. But since the right column won't necessarily be as tall as the left column, positioning .bottom with bottom:0 won't necessarily place it at the bottom of the container.
2. HTML tables and CSS tables
The flexible widths can be achieved by giving the left cell a width of 1px and not specifying a width for the right cell. Both cells will grow to fit the content. Any extra space will be added to the right cell alone.
If .bottom is inside the right table cell, the position can't be achieved in Firefox. Relative position has no effect in a table cell in Firefox; absolute position and 100% width would not be relative to the right table cell.
If .bottom is treated as a separate table cell in the right column, the correct heights of the right and bottom table cells cannot be achieved in any browser other than Firefox. Table cells aren't flexible in height the same way they are in width (except in Firefox).
3. CSS3 flexbox and CSS3 grids
Flexbox and grids are the promising layout tools of the near future. But flexbox isn't supported by IE9 or earlier, and grids aren't supported by any browser other than IE10. Haven't tested if either can achieve this layout, but browser support may prevent them from being an option at present.
Summary
Floats don't offer a solution for any browser.
HTML tables and CSS tables don't offer a cross-browser solution.
Flexbox doesn't offer a potential solution for IE9 or earlier (and may or may not offer a solution to other browsers).
Grids only offer a potential solution to IE10 (and may or may not offer a solution there).
Conclusion
There doesn't appear to be an adequate CSS solution at present, one that would work in enough relevant browsers, with the possible exception of flexbox (if support for IE9 and earlier isn't required).
jQuery
Here's a couple modified demos that use jQuery to force the columns to have the same height. The CSS and jQuery for both demos is the same. The HTML only differs by how much content is in the left and right column. Both demos tested fine in all browsers. The same basic approach could be used for plain JavaScript.
Taller content on the left
Taller content on the right
To keep things simple, I moved the internal padding for the left and right div to a child element (.content).
Sibling elements of same height and staying on the same row can be achieved by displaying them as table-cell and parent as display: table.
Working fiddle: http://jsfiddle.net/SgubR/2/ (which also display the overflow: hidden along a floating element technique for creating a column. The latter needs a clearfix)
Table-cell in CSS uses any HTML element you want (section, div, span, li, whatever), its semantics is unrelated to table, tr and td elements used for table layout (except that the visual result is the same, that's what we want).
display: table is set on a parent
display: table-row may be used on an element in-between but if it works without it, fine
display: table-cell is set on each child
a width is set on none, some or all these "cells". Browser will adapt both to content and widths set in order to calculate their widths (and total width of parent, obviously)
table-layout: fixed will tell browsers to switch to the other table layout algorithm where they don't care about the quantity of content, only to widths set by CSS
vertical-align: top will be needed in most cases (but you may set other values, great for complex layouts)
margins aren't applied on "cells", only padding. Margins only apply on table itself. Though you still can separate "cells" with border-collapse: separate and/or border-spacing: 4px 6px
Compatibility: IE8+
Fallback for IE6/7 if needed is exactly the same as for inline-block
Longer explanations in previous answers: here and there with also the good old method of faux-columns (your design must be thought with this technique in mind)
Just add an oveflow to the right column and don't float it.
.right {
position: relative;
overflow: hidden;
}
This will make right to fill the rest of the width.
Something like this might work:
http://jsfiddle.net/PCvy9/2/
The main key of what you're looking for lines in the:
.right {
overflow: hidden;
background-color: #C82927;
}
This is due to something called the "block formatting context." Great reasoning and tutorial as to why here: http://colinaarts.com/articles/the-magic-of-overflow-hidden/#making-room-for-floats
However, their heights are not completely linked; in this example, your left side block's height would still need to be manually set (as it's a floated container)

How can I make my DIV just the size of the text it encloses

I have this code:
<div id="one">
<div id="two">my text here</div>
</div>
I have styled the div with id=two and put a box around it. The problem is that it doesn't enclose the text but instead expands to the width of the outer DIV. Is there a way I can make it just size to match the text without specifying width?
You can either
#two {
display: inline; /* or 'inline-block' */
}
Or:
#two {
float: left; /* or right */
}
display: inline; stops the div being displayed as a block-level element, causing it to collapse (for want of a better word) to the size of its contents. If you use the alternative display: inline-block then the div retains its ability to have a defined width and height, which may be required for your layout. However it's worth noting that Internet Explorer 6 and 7 only accepts display: inline-block for those elements that are 'naturally inline.'
float has much the same effect; but using float might/will obviously affect the layout of the page, and may need to be cleared by subsequent elements.
display:inline-block;
This way you keep the block behaviour of your div.

span tag height in Firefox

Using CSS,
I'm trying to specify the height of a span tag in Firefox, but it's just not accepting it (IE does).
Firefox accepts the height if I use a div, but the problem with using a div is the annoying line break after it, which I can't have in this particular instance.
I tried setting the CSS style attribute of: display: inline for the div, but Firefox seems to revert that to span behavior anyway and ignores the height attribute once again.
You can set any element to display: inline-block to allow it to receive a height or width. This also allows you to apply any other "block styles" to an element.
One thing to be careful about however is that Firefox 2 does not support this property. Firefox 3 is the first Mozilla-based browser to support this property. All other browsers support this property, including Internet Explorer.
Keep in mind that inline-block does not allow you to set text alignment inside the element on Firefox if running in quirks mode. All other browsers allow this as far as I know. If you want to set text-alignment while running in quirks mode, you'll have to use the property -moz-inline-stack instead of inline-block. Keep in mind this is a Mozilla-only property so you'll have to do some browser detection to ensure only Mozilla gets this, while other browsers get the standard inline-block.
<style>
#div1 { float:left; height:20px; width:20px; }
#div2 { float:left; height:30px; width:30px }
</style>
<div id="div1">FirstDiv</div>
<div id="div2">SecondDiv</div>
As long as the container for whatever is holding div's 1 and 2 is wide enough for them to fit, this should be fine.
Inline elements can't have heights (nor widths) like that. SPANs are already display: inline by default. Internet Explorer is actually the broken browser in this case.
Since you're displaying it inline, the height should be set at the height of your line-height attribute.
Depending on how it's laid out, you could always use float:left or float:right on the span/div to prevent the line break. But if you want it in the middle of a sentence, that option is out.
The problem is that 'display: inline' can't get a height associated because, being inline, it gets its height from its the content. Anyway, how do you define the height of a box that is broken at the end of a line?
You might try to set 'line-height' instead, or if this doesn't work to your satisfaction, set a padding:
/* makes the whole box higher by inserting a space between the border and the content */
padding: 0.5em 0;
You can only change the height (and width) of a span element when it is set to display: block;. This is because it is an inline element normally. div is set to display: block; normally.
A solution could be to use:
<div style="background: #f00;">
Text <span style="padding: 14px 0 14px 0; background: #ff0;">wooo</span> text.
</div>
To set height of span following should work in firefox
span {
display: block;
height: 50px;
}
text alignment inside the element you can adjust using the padding and block-inline attributes. display:inline-block; padding-top:3px; for example
height in em = relative line-height
for example height:1.1em with line-height:1.1
= 100% filled