Display:table + display: table-cell does vertical align but divs have nonsense widths - html

I have a code to create wrapper divs containing elements I want to be vertically centered.
Ok. This works fine for me, I can have a given height for top-parent container or a given height for one of the elements contained (img, span, etc). I have always a right vertically centered of elements (this is what I want)
But however I have this error.
The widths of divs have an arbitrary value, as if the browser distributed the space.
I cannot use 'float' because then the table-trick does not work.
The next example I have three divs and I have arbitrary widths....
I'd like the first and second divs aligned to the left, and the third to the right.
But I can't use float ,, this is the code ( the imgs are 'cut' , but you can see the pseudo-image)
<div style="display: table; width: 200px; background-color: #0099CC;">
<div style="vertical-align: middle; display: table-cell;">
<img src="data:image/png;base64,iVBORw0KGg..."=" width="32" height="82"></div>
<div style="vertical-align: middle; display: table-cell;">
<span>Load file</span></div>
<div style="display: table-cell; text-align: center; vertical-align: middle;">
<img src="data:image/png;base64,iVBORw0KGg..."=" width="32" height="32"></div>
</div>
Any idea would be really appreciated,

Use the following process:
Replace display:table with display:inline-block
Use a container div with position:relative
Use text-align: justify to spread out the elements equally
Use a nested div with position:absolute; right:0; to realign the third element
Here are some related questions:
How to stretch a fixed number of horizontal navigation items evenly and fully across a specified container
Styling overlapping annotations in text with HTML <SPAN> tags and CSS

Related

Why does setting padding on an element affect all siblings in the same div

In this fiddle I have a load of divs, an input and some images that are displayed inline. I want to shift the images down a bit so it looks nicely aligned, but when I apply padding or margin, it simply pushes down every element inside the container.
<div class="rs-paging">
<div class="rs-pageclick">
<img class="rs-selectfirst" src="http://findicons.com/files/icons/2296/fidelity/32/arrow_left.png" alt="" title="First Page">
</div>
.rs-pageclick img {
cursor:pointer;
display: inline-block;
margin-top: 15px;
}
http://jsfiddle.net/paull3876/qds8pnfx/2/
I've tried display:table/table-cell, no difference. I started without the images in container divs and that was just the same. vertical-align:top doesn't seem to help. And it ssems the same with padding or margin.
I don't really want to resort to position absolute/relative as I think there should be a way with simply setting padding. This is driving me nuts !
thanks
The elements are all set to display: inline-block;. When you give one of the elements a margin-top, you push the whole line down.
Are you trying to get the items to align vertically? If so, you could use vertical-align: middle; on the inline-block elements.
http://jsfiddle.net/nea4w6h3/1/
Using overflow:hidden and fixing height for divs seem to work and fit your requests (I added a div containing all the text ones) :
https://jsfiddle.net/qds8pnfx/5/

Keeping flexbox container centered when child text wraps [duplicate]

This question already has answers here:
Make container shrink-to-fit child elements as they wrap
(4 answers)
Closed 5 years ago.
I am trying to center two div elements side by side in a row with flexbox (display:flex).
The first div element, on the left, just has an image.
The second div element, on the right, has left-aligned inline text of unspecified length.
When the line of text is short enough to fit on one line, both divs are aligned and justified to the center as I expect.
When the line of text is long enough to wrap onto two lines, the second div element does not wrap itself around the content as I expect. Instead, it leaves a large white space on the right side of the div.
I mocked up an example here: http://codepen.io/anon/pen/NGqYQX?editors=110. Vary your browser window's width to see what I mean.
How can I set the second div element to shrink itself to fit the text, so that both div elements appear centered?
.flexbox-container {
display: flex;
justify-content: center;
align-items: center;
}
.div1 {
margin-right: 30px;
}
.div2 {
font-size: 48px;
line-height: 48px;
text-align: left;
}
<div class="flexbox-container">
<div class="div1">
<img src="http://dreamatico.com/data_images/kitten/kitten-2.jpg" width="150px">
</div>
<div class="div2">
This is an example of a line of text.
</div>
</div>
<br>
<div class="flexbox-container">
<div class="div1">
<img src="http://dreamatico.com/data_images/kitten/kitten-2.jpg" width="150px">
</div>
<div class="div2">
This is an example of a much loooooooooooooonger line of text.
</div>
</div>
Here is a Photoshop mockup showing what I am trying to do:
In order to achieve your goal (as specified in your second image) we need to make a few adjustments to your HTML and CSS. Everything can be done with flexbox.
HTML
<div id="flex-container-main">
<div class="flex-container-child">
<figure>
<img src="http://dreamatico.com/data_images/kitten/kitten-2.jpg" width="150px">
</figure>
<p>This is an example of a line of text.</p>
</div>
<div class="flex-container-child">
<figure>
<img src="http://dreamatico.com/data_images/kitten/kitten-2.jpg" width="150px">
</figure>
<p>This is an example of a much loooooooooooooonger line of text.</p>
</div>
</div><!-- end #flex-container-main -->
CSS
#flex-container-main {
display: flex;
flex-direction: column;
align-items: center;
}
.flex-container-child {
display: flex;
align-items: center;
min-height: 127px;
width: 75%;
margin: 10px;
}
figure {
margin: 0 20px 0 0;
}
img {
width: 150px;
height: 127px;
vertical-align: bottom;
}
p {
font-size: 48px;
margin: 0;
}
Revised Codepen Demo
Here's what's happening...
Your question asks:
Keeping flexbox centered when text wraps to 2 or more lines
I am trying to center two div elements side by side in a row with flexbox (display:flex).
Let's quickly go over your two images.
Image 1
Image 2
In image 1 all flex items are actually centered. The blue highlight from Chrome Dev Tools emphasizes this point. Each item is perfectly centered on the screen.
Yes, it does get a bit clunky as you re-size the screen smaller – mostly because of the large font size – but the flex items remain centered nonetheless.
In image 2, the flex items are not evenly centered. What you've created in your mock-up is more like a column containing both flexboxes, and the column is centered. But individually only the first row is centered on the screen.
A couple of notes about your code:
With justify-content declared on the flex containers, you are centering the flex items. The flex container itself is not centered.
Since both flexboxes are direct children of the <body>, and <body> has no defined width, the flexboxes align themselves in relation to the viewport.
So to achieve the effect you want we can wrap all your existing mark-up in a new flex container (#flex-container-main). This converts the original flex containers into flex items, which can then be evenly centered as a group.
The new flex items (now classed as .flex-container-child) are given a width to create space and a minimum height based on the height of the image. Each flex item is also declared a flex parent (display: flex) which allows us to use flex properties on child elements. In particular, this is useful for vertically centering the text (as shown in your images).
(Note that my use of HTML semantic elements is not necessary for the code to work. If you prefer the original div tags just swap them back. The important adjustment is the new parent container.)
Lastly (and this may not be important to your layout but just in case), browsers normally give images a small gap of whitespace under their bottom border. This is used to accommodate descenders. With vertical-align: bottom, this space is removed. (For more details see my answer about descenders.)

display:table-cell doesn't work properly with 100% width

I wanted to align text vertically inside of div:
display:table-cell;
vertical-align: middle;
Text is getting aligned, but div (which has 100% width) becomes smaller in width. What is the problem? Is there any other good way to align vertically?
EDIT: little more HTML code:
<div style="position:absolute;top:40%;left:0%;">
<div id="posts" style="position:relative;">
<div style="display:table-cell;vertical-align: middle;width:100%;height:100px;position:relative;text-indent: 1.5em"></div>
<div style="display:table-cell;vertical-align: middle;width:100%;height:100px;position:relative;text-indent: 1.5em"></div>
</div>
</div>
An element displayed as table-cell without any parent explicitly displayed as table will create its own shadowy parent displayed as such (and another in-between set as table-row). It's nowhere to be seen in the DOM but it still have an effect.
The default table layout algorithm is table-layout: auto and you want table-layout: fixed: former layout algorithm will adapt dimensions of cells to your content; latter will respect what the author (you) says for widths. You can test by having very little content in 1 "cell" and then a very long multi-line content.
#posts {
position: relative;
display: table;
table-layout: fixed;
width: 100%;
}
You also should remove or adapt widths on cells: total should be 100% or else it'll be proportional on most browsers (Safari being at risk. Maybe not Saf 8 but 6 at least...)
I have updated your code to get it to work:
<div style="position:absolute;top:40%;left:0%;width:100%;">
<div id="posts "style="position:relative;width:100%;">
<div style="display:table; width:100%;">
<div style="display:table-cell;vertical-align: middle;width:100%;height:100px;position:relative;text-indent: 1.5em;text-align:center;">test
</div>
</div>
</div>
What you needed was to add a div with display: table in and set all the containing elements to 100% width. Also the div you are centring needed a text-align: center.

Tricky vertical align center with css

I found different suggestions on how to vertically align stuff using css. However, none of those could handle what I wanted. Here is what I want:
In general I have some text that should fill the left half of some space and a picture that should be in the right half of the space.
If the height of the text is smaller than the picture both text and picture should vertically align at top of the space:
TextTextText PicturePicture
TextTextText PicturePicture
PicturePicture
If the height of the text is greater than the height of the picture, then the the text should vertically align on top and the picture at the middle relative to the text.
TextTextText
TextTextText PicturePicture
TextTextText PicturePicture
TextTextText PicturePicture
TextTextText
Here is one straight forward way I tried (text-version without picture):
<div style="width: 100%">
<div style="width: 50%; display: inline-block; vertical-align: top;">
TextTextText <br>
TextTextText <br>
TextTextText
</div><div style="width: 50%; display: inline-block; vertical-align: middle;">
PicturePicture <br>
PicturePicture
</div>
</div>
However, the effect I intended was not achieved. The right inner div (Picture) is just aligned on top rather than in the middle relative to the text. There is no difference between setting vertical-align: middle and vertical-align: top. However, interestingly setting vertical-align: bottom makes a difference.
The outer div is contained in some other element of a certain width. However, I cannot specify this width by any fixed measure, e.g. px. Same for the two inner divs with equal width.
Making the inner divs table cells achieved the right vertical effect. However, I cannot use display: table-cell, since I need to make sure that the left inner div maintains its width even though the right inner div could have content that overflows to the right, like PicturePicturePicturePicturePicture.... This would lead to shrinking the width of the left cell, which I don't want.
Furthermore, I do not know the height of the content, so none of the tricks for vertical alignment that use a fixed height works.
It seemed not an too uncommon task, but I was unable to find any solution. Is it possible to do this?
It's not clear to me what behaviour you want when the picture is too wide for the right inner div, other than it should not affect the width of the left inner div, but does this meet your requirements?
HTML.
<div class="container">
<div class="caption cell">
Text Text Text <br/>
Text Text Text <br/>
Text Text Text <br/>
Text Text Text <br/>
Text Text Text <br/>
Text Text Text
</div>
<div class="picture cell">
<div>
<img src="http://placehold.it/500x50" />
</div>
</div>
</div>
CSS
.container {display:table; table-layout: fixed; width:100%; }
.cell { display: table-cell; width:50%; }
.caption { vertical-align: top; }
.picture { vertical-align: middle; }
.picture div { overflow-x:hidden; }
JSFiddle at http://jsfiddle.net/92wcy/1/
If you don't want the left column to shrink then add a min-width to it.
http://jsfiddle.net/pUbWt/1/
.container {
display: table;
width: 100%;
}
.container .caption, .container .picture {
display: table-cell;
}
.container .caption {
vertical-align: top;
min-width: 10em;
}
.container .picture {
vertical-align: middle;
}
Flexbox would also work, but its a little early to start using in production sites.
Vertical alignment is always tricky as CSS wasn't made to accomplish that.
Still, is this what you were after? http://jsfiddle.net/N7px2/
If so, read on.
First, I removed your inline styles as this is bad practice. Simply use <style>...</style> in the head of your HTML, or even better: Use an external CSS file.
Then, I floated your divs #b and #c to align them like in your example. See the background-color and border to get a quick idea where each element is placed.
Because floats let the parent element collapse, I used a clearfix to fix that. Read more about that here.
Now the vertical alignment: I positioned the image in #c absolute and gave it a margin top: 50%. Obviously that pushed the image too much, but that's how it works. After that, I applied a negative margin-top: -25% to pull the image back in place. Please take note that this only works if the parent element is relative positioned.
The browser support for negative margins is really good and as long they aren't used to fix a bad layout it's alright to use them.
And another note: Because position: absolute takes an element out of the flow, #c collapses. If you wanted to give #c a background-image or something similar, you need a bit more markup to fix that - simply add another div.
Hope that helped you in any way!
Edit: Sorry, I just realised that this code isn't exactly what you were after I believe.

Three part dynamic spacing wo/Table and Absolute Positioning

I'm trying to place 3 divs within a larger div such that the center one is 800px wide, and centered, and the other two fill the space remaining. I cannot use tables, nor can I use absolute positioning, as I have html below that must be outside the three divs but inside the larger div. I can get the center div:
.center-div {
width: 800px;
margin-left: auto;
margin-right: auto;
}
But how do I position the other two divs?
<div id="outer">
<div id="left-div"></div>
<div id="center-div"></div>
<div id="right-div"></div>
</div>
You could try messing around with display: table-row; for the container div and display: table-cell; for the inner divs. You might even need a second container with display: table;—the basic idea is emulating a table without using table, tr, and td.
All those table-values for the display property are specified in CSS 2.1, but I have never personally tested which browsers support them. I’ll bet my money though that IE6 won’t be able to cope with it. ;-)