vetical-align a line of text in container - html

After reading something on vertical-align here, i'm decide to do some practice on this feature, but stuck into a problem that really hard to understand. could you please figure out why "the line of text" does not get vertical-aligned in wrapper div.
.wrapper {
height: 200px;
background-color: aquamarine;
margin: 0;
padding: 0;
}
.ctxt {
display: inline-block;
vertical-align: middle;
margin: 0;
padding: 0;
}
.ctxt-before {
display: inline-block;
width: 10px;
height: 200px;
background-color: #f66;
margin: 0;
padding: 0;
}
<div class="wrapper">
<!-- i think the line-box is 200px and div.ctxt should vertical-aligned in div.wrapper -->
<div class="ctxt-before"></div>
<p class="ctxt">this line of text</p>
</div>
I think the line-box is 200px and div.ctxt should vertical-aligned in div.wrapper.

You've almost got the idea, but you're aligning the middle of the ctxt div with the baseline of the ctxt-before div. Because that has no content, its baseline is its bottom edge.
You need to align it with the middle of the ctxt-before div instead:
.wrapper {
height: 200px;
background-color: aquamarine;
margin: 0;
padding: 0;
}
.ctxt {
display: inline-block;
vertical-align: middle;
margin: 0;
padding: 0;
}
.ctxt-before {
display: inline-block;
width: 10px;
height: 200px;
background-color: #f66;
margin: 0;
padding: 0;
vertical-align: middle; /* add this */
}
<div class="wrapper">
<!-- i think the line-box is 200px and div.ctxt should vertical-aligned in div.wrapper -->
<div class="ctxt-before"></div>
<p class="ctxt">this line of text</p>
</div>

The reasons why you got that result is:
div.ctxt-before is not vertical-aligned in middle. By default, inline or inline-block element is aligned on baseline.
div.ctxt-before does not contain text or image, so the baseline is the bottom of its bounding box. If you try adding text inside div.ctxt-before, the text in p.ctxt will display at top, because the baseline belongs to text/image, not the bounding box anymore.
If you just want div.ctxt-before element and p.ctxt element to be vertical-aligned in middle, you miss:
.ctxt-before{vertical-align: middle;}

Using flex box you can do this easily.
.wrapper {
height: 200px;
background-color: aquamarine;
align-items: center;
text-align: center;
display: flex;
justify-content: center;
}
https://codepen.io/ssniranga/pen/dqKaNe

Yours doesn't work because vertical-align is for tables. When display modes, box-model, and positions are considered, it's easy to see that css layout has many aspects. You'll have to read about them to truly understand what's going on.
Try using flexbox, they make this stuff easy:
.wrapper {
height: 200px;
background-color: aquamarine;
display: flex;
justify-content: center;
align-items: center;
}
.ctxt-before {
display: inline-block;
width: 10px;
height: 200px;
background-color: #f66;
margin: 0;
padding: 0;
}
<div class="wrapper">
<!-- i think the line-box is 200px and div.ctxt should vertical-aligned in div.wrapper -->
<div class="ctxt-before"></div>
<p class="ctxt">this line of text</p>
</div>

Related

Why is my <div> being pushed up under my header when I add another element? [duplicate]

This question already has answers here:
Can't scroll to top of flex item that is overflowing container
(12 answers)
Closed 4 years ago.
I must be forgetting something fundamental with my vertically and horizontally centered flexbox.
The container is within a parent with vertical scroll, and when the container becomes too tall, it grows beyond the parent top, clipping the content. The bottom stays put.
Try adjusting the height of the view or adding more lines to see it in action.
body,
html {
height: 100%;
width: 100%;
margin: 0;
}
* {
box-sizing: border-box;
}
#wrapper {
background: grey;
height: 100%;
width: 100%;
max-height: 100%;
display: flex;
overflow-y: auto;
align-items: center;
justify-content: center;
}
#box {
margin: 30px 0;
background: white;
border: 1px solid #dfdfdf;
}
<div id="wrapper">
<div id="box">
First line
<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br> Last linje
</div>
</div>
How do I keep it from getting clipped? Additionally I'm trying to have a 30px margin above and below the container.
Thanks!
You forgot nothing but you simply need to understand what is happening. First you made your wrapper to be 100% height of screen and then you made the box to be centred vertically and horizontally. When the box has a big height you will have something like this:
Now, when you add overflow-y: auto you will create a scroll that will start from the top of the wrapper until the bottom overflowed content. So it will be like this:
That's why you are able to scroll to the bottom to see the bottom part and not able to see the top part.
To avoid this, use margin:auto to center your element and in this case we will have two situations:
When box-height < wrapper-height we will have the space spread equally on each side because of the margin:auto thus your element will be centred like expected.
When box-height > wrapper-height we will have the normal behavior and your element will overflow and his top edge will stick to the top edge of the wrapper.
You may also notice the same can happen horizontally that's why I will use margin to center on both directions.
body,
html {
height: 100%;
width: 100%;
margin: 0;
}
* {
box-sizing: border-box;
}
#wrapper {
background: grey;
height: 100%;
width: 100%;
max-height: 100%;
padding:30px 0;
display: flex;
overflow-y: auto;
}
#box {
margin: auto;
background: white;
border: 1px solid #dfdfdf;
}
<div id="wrapper">
<div id="box">
First line
<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br> Last linje
</div>
</div>
I think what you want is to make your flex item (#box) have a height and set it's overflow, not the flex container. Also, to add your 30px above and below I would remove the margin from the box and instead add padding to the container.
So, updated styles would look like this:
#wrapper {
background: grey;
height: 100%;
width: 100%;
max-height: 100%;
display: flex;
align-items: center;
justify-content: center;
padding: 30px 0; /*added*/
}
#box {
background: white;
border: 1px solid #dfdfdf;
overflow-y: auto; /*added*/
height: 100%; /*added*/
}
body,
html {
height: 100%;
width: 100%;
margin: 0;
}
* {
box-sizing: border-box;
}
#wrapper {
background: grey;
height: 100%;
width: 100%;
max-height: 100%;
display: flex;
align-items: center;
justify-content: center;
padding: 30px 0;
}
#box {
background: white;
border: 1px solid #dfdfdf;
overflow-y: auto;
height: 100%;
}
<div id="wrapper">
<div id="box">
First line
<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br> Last linje
</div>
</div>
I think you set the top margin in the box class which extends the height of the container. You can maybe set it to padding instead of margin. Hope this helps. Thanks.

DIV element isn't placed correctly next to an image

So I'm questioning myself why the div with the class champ_info isn't placed next to the image because the image is an inline-block element. So the Text in my div element lies under the image instead of next to the image. My code is below.
.champ_info {
background: #0b2e33;
color: white;
}
.champ_container {
background: #10474e;
}
.champ_img {
border: 3px solid #1ba9bd;
border-radius: 50%;
margin: 5px;
height: 5rem;
width: auto;
}
<div class="champ_container">
<img class="champ_img" src="https://ddragon.leagueoflegends.com/cdn/9.5.1/img/champion/Pyke.png">
<div class="champ_info">
Some Text
</div>
</div>
Thank you in advance.
I personally find making inherently block level elements inline counter intuitive. Flex box is the perfect solution to your problem.
.champ_container {
width: 40%;
margin: 0 auto;
display: flex;
/* justify-content: center; */
align-items: center;
background: #10474e;
}
.champ_info {
background: #0b2e33;
color: white;
width: 100%;
height: 100%;
}
.champ_img {
border: 3px solid #1ba9bd;
border-radius: 50%;
margin: 5px;
height: 5rem;
width: auto;
}
<div class="champ_container">
<img class="champ_img" src="https://ddragon.leagueoflegends.com/cdn/9.5.1/img/champion/Pyke.png">
<div class="champ_info">
Some Text
</div>
</div>
<div> is a block element, which means it takes up the whole line. Put display: inline; inside the css for the <div> and it places it next to the image like you wanted.
Add vertical-align: top; if you want the text to align to the top. Since the image and the text align to the bottom of the parent, you need to manually set them to align to the top.
.champ_info {
background: #0b2e33;
color: white;
display: inline;
vertical-align: top;
}
.champ_container {
background: #10474e;
}
.champ_img {
border: 3px solid #1ba9bd;
border-radius: 50%;
margin: 5px;
height: 5rem;
width: auto;
}
<div class="champ_container">
<img class="champ_img" src="https://ddragon.leagueoflegends.com/cdn/9.5.1/img/champion/Pyke.png">
<div class="champ_info">
Some Text
</div>
</div>

CSS3 flexbox: vertically center two different sized items, but make their top align at the same height

inspired by:
Flexbox - Vertically Center and Match Size
fiddle with the problem:
http://jsfiddle.net/Nbknc/22/
what i try to achieve:
I want to get the text of the second button to start at the same height as the text on the first button.
HTML
<section class="buttonsSection">
<a class="button" href="#">Very Long Word aaaa xx ccc ddd ee</a>
<a class="button" href="#">Short Phrase</a>
</section>
CSS
.button {
padding: 10px 15px;
width: 150px;
background-color: deepskyblue;
color: white;
margin: 3px;
text-align: top;
display: flex;
flex-direction: column;
justify-content: center;
}
.buttonsSection {
margin: 30px 0;
display: flex;
justify-content: center;
height: 500px;
}
body
{
width: 20%; /*Simulate page being reduced in size (i.e. on mobile)*/
margin: 0 auto;
}
a photo of how i want it to look
EDIT the reason I use flexbox and justify-content is to make it work with different screen sizes. Space is perfectly distributed with flexbox. Adding a padding is suboptimal as it will stay the same, even if the screen has a height of say 200px.
Here is one way, one where I added an extra wrapper that centers
.buttonsSection {
display: flex;
flex-direction:column;
justify-content: center;
height: 400px;
border: 1px solid;
width: 200px;
margin: 0 auto;
}
.buttonsWrap {
margin: 30px 0;
display: flex;
}
.button {
padding: 50px 15px;
width: 150px;
background-color: deepskyblue;
color: white;
margin: 3px;
text-align: top;
}
<section class="buttonsSection">
<div class="buttonsWrap">
<a class="button" href="#">Very Long Word aaaa xx ccc ddd ee</a>
<a class="button" href="#">Short Phrase</a>
</div>
</section>
You can accomplish this by removing the flexbox properties from the button and adding a span around your button text with the following CSS:
position: relative;
top: 50%;
transform: translateY(-50%);
You may need to play with those percentages to get things to line up ideally, but this gets you in the ballpark.
http://codepen.io/angeliquejw/pen/QNdrOZ?editors=0100
I updated the fiddle
Suggest if its not that you require.
http://jsfiddle.net/Nbknc/30/
.button {
padding: 50% 15px 0 15px;
width: 150px;
background-color: deepskyblue;
color: white;
margin: 3px;
}
.buttonsSection {
margin: 30px 0;
display: flex;
flex-direction:row;
height: 500px;
}
Now its much simpler , now you can add the required padding to your button
so that the text in both button will align with equal top padding .
UPDATE
included some changes to your html and css
http://jsfiddle.net/Nbknc/32/
Edit: http://jsfiddle.net/Dneilsen22/36yL3y5m/5/
Removing the justify-content for .button and increasing the top padding would accomplish this.
.button {
padding: 100px 15px;
width: 150px;
background-color: deepskyblue;
color: white;
margin: 3px;
text-align: top;
display: flex;
flex-direction: column;
}

Center align with table-cell

I'm trying to use the table-cell way to center a div vertically and horizontally.
It works when I use the following code:
div {
display: table;
}
.logo {
display: table-cell;
position: absolute;
vertical-align: middle;
left: 0;
right: 0;
bottom: 0;
top: 0;
margin: auto;
}
But I'd rather wrap .logo in another div called .center like here JSFiddle, but for some reason, although it works in JSFiddle, it isn't working for me on my site.
Here is a good starting point.
HTML:
<div class="containing-table">
<div class="centre-align">
<div class="content"></div>
</div>
</div>
CSS:
.containing-table {
display: table;
width: 100%;
height: 400px; /* for demo only */
border: 1px dotted blue;
}
.centre-align {
padding: 10px;
border: 1px dashed gray;
display: table-cell;
text-align: center;
vertical-align: middle;
}
.content {
width: 50px;
height: 50px;
background-color: red;
display: inline-block;
vertical-align: top; /* Removes the extra white space below the baseline */
}
See demo at: http://jsfiddle.net/audetwebdesign/jSVyY/
.containing-table establishes the width and height context for .centre-align (the table-cell).
You can apply text-align and vertical-align to alter .centre-align as needed.
Note that .content needs to use display: inline-block if it is to be centered horizontally using the text-align property.
This would be easier to do with flexbox. Using flexbox will let you not to specify the height of your content and can adjust automatically on the height it contains.
DEMO
here's the gist of the demo
.container{
display: flex;
height: 100%;
justify-content: center;
align-items: center;
}
html
<div class="container">
<div class='content'> //you can size this anyway you want
put anything you want here,
</div>
</div>

CSS resize div that has display: table-cell

I have a header on my site, and this has a container and three divs.
The heading container is 100px high.
The first div floats to the left and has a width of 150px
The second div floats to the right and has a width of 150px
The third div has another div inside it, and by default resizes to fill the remaining space.
I want the third div to center vertically. When I add display: table-cell and vertical-align: middle the div shrinks to the size of the text. I can only resize the div using a fixed size.
<div id="#headingcontainer">
<div class="leftimg">Left</div>
<div class="rightimg">Right</div>
<div class="heading">Content to be centered horizontally and vertically</div>
</div>
#headingcontainer
{
border: none;
border-bottom: 2px solid #8c8cd4;
width: 100%;
height: 100px;
text-align: center;
background-color: #000;
margin-bottom: 10px;
margin-left: auto;
margin-right: auto;
}
div.heading
{
display: table-cell;
vertical-align: middle;
height: 100px;
text-align: center;
width: auto;
}
div.leftimg
{
width: 150px;
float: left;
}
div.rightimg
{
width: 150px;
float: right;
}
Can anyone let me know how I can center the middle div without knowing the exact width?
If I take out the display: table-cell from the heading class it is no longer centered vertically but is horizontally.
I think this might be what you're looking for... I changed div.header in the css to have padding on top, removed the table-cell and also set the margin to auto instead of width auto. See if this is what you were hoping for. You will have to adjust the padding on top depending on the spacing but this seems like the easiest way to me.
#headingcontainer
{
border: none;
border-bottom: 2px solid #8c8cd4;
width: 100%;
height: 100px;
text-align: center;
background-color: #000;
margin-bottom: 10px;
margin-left: auto;
margin-right: auto;
}
div.heading
{
height: 100px;
text-align: center;
margin: auto;
padding-top:40px;
}
div.leftimg
{
width: 150px;
float: left;
}
div.rightimg
{
width: 150px;
float: right;
}
<div id="headingcontainer">
<div class="leftimg">Left</div>
<div class="rightimg">Right</div>
<div class="heading">Content to be centered horizontally and vertically</div>
</div>
I have now found an answer that works for me.
First a small change to the HTML (two extra divs in the heading):
<div id="#headingcontainer">
<div class="leftimg">Left</div>
<div class="rightimg">Right</div>
<div class="heading"><div><div>Content to be centered horizontally and vertically<div></div></div>
</div>
Then change to the CSS:
#headingcontainer
{
border: none;
border-bottom: 2px solid #8c8cd4;
background-color: #000;
margin-bottom: 10px;
width: 100%;
height: 100px;
}
div.heading
{
display: table;
border-collapse: collapse;
width: 100%;
height: 100px;
position: absolute;
}
div.heading div
{
display: table-row;
}
div.heading div div
{
display: table-cell;
text-align: center;
vertical-align: middle;
}
This allows the final div contain the text to be both centered vertically and also horizontally. The help came from another Stack Overflow question I found after more searching - 818725.
try this http://jsfiddle.net/KtgVN/20/