CSS - line-height padding of wrapped text not what I expect - css

Having some problems getting the correct css to align the text the way I would like.
.html file
<section id='a'>
<div class='b'>111</div>
<div class='b'>222</div>
<div class='b'>33333</div>
<div class='b'>444444 4444</div>
<div class='b'>55555</div>
</section>
.css file
#a {
position: fixed;
top: 50%;
left: 5vw;
transform: translateY(-50%);
}
.b {
position: relative;
margin: 5px;
height: 56px;
width: 56px;
text-align: center;
vertical-align: middle;
line-height: 56px;
font-size: 14pt;
color: #696969;
background-color: #D3D3D3;
border-radius: 30px;
cursor: pointer;
border: 2px solid #000000;
}
Things display fine except for div 4 which has longer text which stretches outside.
I added a class to change the line height so the text wraps:
<div class='b c'>444444 4444</div>
.c {
line-height: 28px;
}
I would like to reduce the spacing between the lines so the text has a better fit inside the circle:
.c {
line-height: 18px;
}
I like the spacing, but would like to shift the text down into the center so I added some padding inside the border:
.c {
line-height: 18px;
padding-top: 6px;
padding-bottom: 0px;
}
The circle is expanded into more of an ellipse-type shape.
The height is explicitly stated as 56px.
The margin is 5px (x2 for top and bottom): 10px
The border is 2px (x2 for top and bottom): 4px
The content is two lines of wrapped text with a line height of 18px (x2): 36px
Adding padding of 6px results in 56px which is the specified height, so I am unclear why the padding would expand the height.
Looked into line-height a bit and clearly I don't really understand how that works. I have tried many other settings and values, but nothing that gives me my desired result.
Same behavior in Chrome, Firefox, Opera, and Safari.
Any thoughts, direction, or clarification on what I am doing wrong?

Size of the divs are 56x56 pixels. Once you add any padding (padding-top: 6px), it will add up to 56px, which will result in 62px. Your div (circle) will become an egg. What you need to do is set box-sizing: border-box on the div.
Initial value of box-sizing is content-box. The height you enter is the content's height. Any padding and border isn't included in that value and will expand the div. box-sizing: border-box on the other hand, will keep the div 56px even after you enter a padding. It'll decrease the height of the content and keep the box at the same height.
#a {
position: fixed;
top: 50%;
left: 5vw;
transform: translateY(-50%);
}
.b {
position: relative;
margin: 5px;
height: 56px;
width: 56px;
text-align: center;
vertical-align: middle;
line-height: 56px;
font-size: 14pt;
color: #696969;
background-color: #D3D3D3;
border-radius: 30px;
cursor: pointer;
border: 2px solid #000000;
}
.c {
line-height: 28px;
line-height: 18px;
box-sizing: border-box;
padding-top: 9px;
}
<section id='a'>
<div class='b'>111</div>
<div class='b'>222</div>
<div class='b'>33333</div>
<div class='b c'>444444 4444</div>
<div class='b'>55555</div>
</section>

display: table; and display: table-cell; is a good solution for vertical alignment, regardless of the properties of the child element.
.container {
display: table;
border: 1px solid red;
text-align: center;
}
span {
display: table-cell;
vertical-align: middle;
}
.one {
width: 100px;
height: 100px;
}
.two {
width: 200px;
height: 200px;
}
.three {
width: 75px;
height: 75px;
}
<div class="container one">
<span>some text</span>
</div>
<div class="container two">
<span>some other text</span>
</div>
<div class="container three">
<span>some text that stretches longer</span>
</div>

padding counts toward element size. So height: 56px and padding-top: 6px will make the element 62px high. Just adjust the height of that element to 50px (desired height minus vertical padding, 56 - 6).
Another option is to change box-sizing to border-box (default value is content-box). Which will make padding and border-width to be considered by width and height - https://developer.mozilla.org/en/docs/Web/CSS/box-sizing

You could do something like this:
.b {
position: relative;
top: 50%;
transform: translateY(-50%);
}
and add a wrapper with
transform-style: preserve-3d;

You can use flexbox, where there is no need to calc lines and match padding against size, this does it all dynamically.
#a {
position: fixed;
top: 50%;
left: 5vw;
transform: translateY(-50%);
}
.b {
position: relative;
margin: 5px;
height: 56px;
width: 56px;
font-size: 14pt;
color: #696969;
background-color: #D3D3D3;
border-radius: 30px;
cursor: pointer;
border: 2px solid #000000;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
}
<section id='a'>
<div class='b'>111</div>
<div class='b'>222</div>
<div class='b'>33333</div>
<div class='b'>444444 4444</div>
<div class='b'>55555</div>
</section>

Related

How to align a text to center horizontally and also to the bottom of page?

I want to align a text to center of the page horizontally and also at the bottom of the page, with a background to text. The text here is variable. I want to break the text into more lines, if it crosses width more than 30% of screen size.
I am either able to align div to center or stick to bottom of the page, but couldn't do both. When I give position to absolute or fixed, The center alignment is missing and I have to give left: 30% to move it right.
This is the HTML
<div class="div-1">
<div class="div-2">
Hey this is an amazing way to do this
</div>
</div>
This is the CSS:
.div-1 {
height: 100vh;
}
.div-2 {
bottom: 10px;
background-color: black;
position: absolute;
color: white;
font-size: 20px;
max-width: 30%;
}
Can someone suggest the perfect way to do this ? Thanks.
For starters, change className to class. Then add
position: fixed;
left: 50%;
bottom: 20px;
transform: translate(-50%, -50%);
margin: 0 auto;
to .div-2
.div-1 {
height: 100vh;
}
.div-2 {
background-color: black;
color: white;
font-size: 20px;
max-width: 30%;
position: fixed;
left: 50%;
bottom: 20px;
transform: translate(-50%, -50%);
margin: 0 auto;
}
<div class="div-1">
<div class="div-2">
Hey this is an amazing way to do this
</div>
</div>
You should use the least amount of tag as possible.
In order to center horizontal, use text-align: center and make sure that the width of the container is 100%.
To reduce the width of the text; use padding for the container.
<footer>
Hey this is an amazing way to do this
</footer>
footer {
position: fixed; bottom: 0; left: 0;
text-align: center; width: 100%; box-sizing: border-box;
padding: 15px 35%; background: blue; color: white;
text-transform: uppercase; font-weight: bold;
}
It should be something like this. You can use className as you are using it in React.
.div-1 {
height: 100vh;
}
.div-2 {
bottom: 0;
background-color: red;
position: absolute;
color: white;
font-size: 20px;
max-width: 30%;
height: 400px;
width: 300px;
margin: 0 auto;
text-align: center;
vertical-align: middle;
line-height: 400px;
}
<div class="div-1">
<div class="div-2">
Hey this is an amazing way to do this
</div>
</div>

padding-top stretches div in chrome

I have code like this:
https://jsfiddle.net/y09dngnj/1/
<div style="border: 1px solid green">
<div class="biddingStat" id="biddingStat0"
style="background-color: #DC0707;opacity: 1;
text-align: center; ">10000
</div>
</div>
.biddingStat {
width: 80px;
position: relative;
bottom: 0px;
background-color: #eeee22;
padding-top: 20px;
/*left: 40px;*/
border-top-left-radius: 10px;
border-top-right-radius: 10px;
min-height: 30px;
height: 100px;
}
If you change css from padding-top: 20px to padding-top: 5px and rerun fiddle, although there is height 100px of red div, the height changes. I'd expect that text would change its position to be more distant from top edge but height of div would stay 100px no matter what.
How to keep 100px height of div and have text padded from top?
Change padding-top to margin-top in the CSS file.
See: CSS Box Model
<div style="border: 1px solid green"><div class="biddingStat" id="biddingStat0" style="background-color: #DC0707;opacity: 1;text-align: center; ">10000</div></div>
<style>
.biddingStat
{
width: 80px;
position: relative;
bottom: 0px;
background-color: #eeee22;
margin-top: 150px;
padding-top: 20px;
/*left: 40px;*/
border-top-left-radius: 10px;
border-top-right-radius: 10px;
min-height: 30px;
height: 100px;
}
</style>
If you don't want padding to affect the dimensions of an element you can use box-sizing: border-box; which will allow the div to not be affected by any padding or borders added to it.

CSS use transform-origin to position a rotated element

I can't work out how to rotate an element so that it sits underneath another one. The image below should illustrate the intended result.
Here is what I have tried so far:
.div1 {
height: 120px;
width: 120px;
float: left;
margin: 20px;
border: solid 1px #000;
overflow: hidden;
}
.div1 button {
width: 48px;
height: 48px;
border: 0;
margin: 0;
padding: 0;
}
.div2 {
background-color: #999;
height: 48px;
line-height: 48px;
box-sizing: border-box;
}
.originFromLeft .div2 {
transform: rotate(90deg);
transform-origin: 24px 24px;
padding-left: 12px;
text-align: left;
}
.div1.originFromRight {
overflow: visible;
}
.originFromRight .div2 {
padding-right: 12px;
text-align: right;
transform: rotate(-90deg);
transform-origin: right top;
}
<div class="div1">
<button>></button>
<div class="div2">HELLO</div>
</div>
<div class="div1 originFromLeft">
<button>></button>
<div class="div2">HELLO</div>
</div>
<div class="div1 originFromRight">
<button>></button>
<div class="div2">HELLO</div>
</div>
The second example basically does what I want but the text is orientated the wrong way.
The closest I can get is example 3 but I need to pull this back to the left. I've tried translate but I can't get it to work, I've tried a negative right margin of 100% which almost works but basically doesn't.
One method to achieve the expected output would be to do the following:
Put the button within div2 and position it at the right edge.
Absolutely position the div2 at the bottom of the parent container.
Rotate the div2 in counter clockwise direction (-90deg) with the transform origin at left bottom.
After rotation, the div2 would entirely go outside of the container and hence we need to add an extra translateY(100%) to the transform stack.
The text is aligned to the right and an extra padding-right (greater than the width of the button) is added to keep the text away from the button.
The button would also get rotated by -90 degree because it is a child of div2 and to counter that (that is to make the button text get displayed properly), we need to apply counter rotation.
Now, in this approach the only drawback is that if the text length increases beyond what can be fit in a single line then it would wrap around to the next line (have a look at the second sample in snippet).
.div1 {
position: relative;
height: 120px;
width: 120px;
float: left;
margin: 20px;
border: solid 1px #000;
overflow: hidden;
}
button {
position: absolute;
display: inline-block;
bottom: 0;
right: 0;
width: 48px;
height: 48px;
border: 0;
margin: 0;
padding: 0;
transform: rotate(90deg);
}
.div2 {
position: absolute;
box-sizing: border-box;
bottom: 0px;
height: 48px;
width: 100%;
padding-right: 60px;
line-height: 48px;
background-color: #999;
text-align: right;
transform: rotate(-90deg) translateY(100%);
transform-origin: left bottom;
}
<div class="div1">
<div class="div2">HELLO
<button>></button>
</div>
</div>
<div class="div1">
<div class="div2">HELLO WORLD!!!!!
<button>></button>
</div>
</div>
I have taken your second example and rotated the element the other way round.
And then fixed the position with an extra translateX
.div1 {
height: 120px;
width: 120px;
float: left;
margin: 20px;
border: solid 1px #000;
overflow: hidden;
}
.div1 button {
width: 48px;
height: 48px;
border: 0;
margin: 0;
padding: 0;
}
.div2 {
background-color: #999;
height: 48px;
line-height: 48px;
box-sizing: border-box;
}
.originFromLeft .div2 {
transform: rotate(-90deg) translateX(-100%);
transform-origin: top left;
padding-left: 12px;
text-align: right;
}
<div class="div1 originFromLeft">
<button>></button>
<div class="div2">HELLO</div>
</div>

Text at bottom in DIV without using Display:Table-Cell in CSS

is there any other proper way to display text at bottom because with Display:Table-Cell, I can't use margin property.
div.Product2 {
display: table-cell;
width: 250px;
height: 120px;
text-indent: 15px;
vertical-align: bottom;
padding-bottom: 10px;
letter-spacing: 1px;
background: url('../images/cp_bg.png') no-repeat center 10px #008f00;
}
The only way I believe you could do this without table-cell would be using multiple divs. You have a choice to either keep the table-cell and place it inside a wrapper div or just put your text into a child div
div.Product2 {
/*display: table-cell;*/
width: 250px;
height: 120px;
text-indent: 15px;
/*vertical-align: bottom;*/
padding-bottom: 10px;
letter-spacing: 1px;
background: url('../images/cp_bg.png') no-repeat center 10px #008f00;
position: relative;
}
div.product3 {
position: absolute;
bottom: 0;
}
<div class="Product2">
Some Text
<div class="product3">
Bottom Text
</div>
</div>
One method of achieving this is to wrap your text within a containing element, like <p>, and apply a CSS transform. This of course won't have broad support unless you use some prefixes.
.Product2 {
width: 250px;
height: 120px;
text-indent: 15px;
padding-bottom: 10px;
letter-spacing: 1px;
background: #008f00;
}
.Product2 p {
position: relative;
top: 100%;
transform: translateY(-100%);
-ms-transform: translateY(-100%);
-webkit-transform: translateY(-100%);
}
<div class="Product2">
<p>Blah blah</p>
</div>
Another way is line-height, since your height is fixed, line-height is a good solution. No need to change your structure. Remove display:table-cell and vertical-align: middle.
div.Product2 {
width: 250px;
height: 120px;
text-indent: 15px;
padding-bottom: 10px;
letter-spacing: 1px;
background: url('../images/cp_bg.png') no-repeat center 10px #008f00;
line-height:220px;
}
<div class="Product2">
Hello World!
</div>

Complicated Double Text Underline

So I'm looking to create an effect where a header font is underlined. I want the underline to stretch the width of the div that the header is in. BUT I want the area of that underline that is directly underneath the text to be in a separate color. So under the text it should be blue, but the moment that underline is no longer underneath the text, it should be grey. I was figuring a double border system would work, but I'm not sure if it's even possible anymore to do this with just CSS...is it?
Here's another quick solution. Change the 500px to anything you want, could be a percentage.
HTML
<div class="blue">
Header
</div>
<div class="grey">
</div>
<div class="clear">
</div>
CSS
.blue {
padding-top: 10px;
padding-bottom: 10px;
border-bottom: 2px solid blue;
float: left;
overflow: hidden;
position: absolute;
z-index: 0;
}
.grey {
padding-top: 10px;
padding-bottom: 10px;
border-bottom: 2px solid grey;
float: left;
width: 500px;
overflow: hidden;
position: absolute;
z-index:-1;
}
.clear {
clear: both;
}
Example: http://jsfiddle.net/UuYvv/
Did this with fixed positioning here. If you try and do it with everything relative, it gets a little funkier but still sort of works. Hope that helps!
html:
<div class="outer">
<div class="word">My Word</div>
</div>
css:
.outer {
left: 0px;
top: 0px;
height: 20px;
width: 200px;
border-bottom: 2px solid grey;
overflow: visible;
position:fixed;
}
.word {
position: fixed;
top: 0px;
width: 80px;
margin-bottom: -1px;
border-bottom: 2px solid blue;
}

Resources