Text at bottom in DIV without using Display:Table-Cell in CSS - 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>

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>

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

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>

Responsive containers with shapes

I am trying to create this layout:
LINK
I need to create 3 containers and each container will have an image as a background. Tried to do it with SVG, but it's not an option, because in future images will be changed via CMS, so I need a shape, that images can fill in. Also tried to play with the border, so I can create a shape, but it's also not working the way it looks on the image above. Is there an easier way to achieve this? Let's say using bootstrap classes?
You can do it in two ways 1)using bootstrap classes 2)using #media and for showing proper image according to div size you can use .className{background-size:contain;background-repeat:no-repeat}
You may use flex, transform and pseudo to hold backgrounds:
/* http://codepen.io/gc-nomade/pen/vGvRPZ */
html,
body {
height: 100%;
width:100%;
margin: 0;
overflow: hidden;
}
body > div {
position:relative;
min-height: 100%;
width:100%;
display: flex;
width: 160%;
margin: 0;
margin-left: -30%;
}
div div {
display: flex;
align-items: center;
transform: skew(-30deg);
overflow: hidden;
border-left: solid;
flex: 4;
position: relative;
}
div div h2 {
font-size: 5vw;
color: turquoise;
text-shadow: 0 0 1px black;
position: relative;
text-align: center;
width: 100%;
transform: skew(30deg);
}
div div:nth-child(1) h2 {
padding-left: 50%;
}
div div:nth-child(3) h2 {
padding-right: 50%;
}
div div:before {
transform: skew(30deg);
content: '';
top: 0;
bottom: 0;
right: -50%;
left: -50%;
position: absolute;
background: url(http://hd.wallpaperswide.com/thumbs/grungy_background-t2.jpg ) center tomato;
background-size: 100vw auto;
}
div div:nth-child(2):before {
background: url(http://www.intrawallpaper.com/static/images/desktop-backgrounds-8656-8993-hd-wallpapers_js7gwWA.jpg) center right gray;
background-size: 100vw auto;
}
div div:nth-child(3):before {
background: url(https://wallpaperscraft.com/image/dark_background_colorful_paint_47176_300x188.jpg) center right turquoise;
background-size: 100vw auto;
}
div div:nth-child(2) {
flex: 2.5;
}
<div>
<div>
<h2>title 1</h2>
</div>
<div>
<h2>title 1</h2>
</div>
<div>
<h2>title 1</h2>
</div>
</div>

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>

Align to left side of contaner a element rotated -90deg

div {
width: 300px;
height: 300px;
border:1px solid black;
}
h1 {
width: 300px;
transform: rotate(-90deg)
}
<div>
<h1>Hola</h1>
</div>
If you try this snippet, you will see that the h1 is rotated and placed in the center of the div (makes sense, they have same width)
But how to align it to the left? (flexible container's width)
You can position the h1 element absolutely with respect to the parent div and then use transform-origin property to specify the axis about which the rotation should happen.
In the below snippet, the element is positioned at the bottom of the parent and because the origin is set at left-bottom, the left-bottom of the element (h1) stays at its position during rotation.
Now because of the rotation, the element would go outside of the parent after rotation. To bring it back into position add translateY(100%) to the transform stack. A text-align: right is added to set the content at left-top. The text-align makes it look a bit more hackish than it actually is but otherwise it is difficult to position at left-top.
div {
position: relative;
width: 300px;
height: 300px;
border: 1px solid black;
}
h1 {
position: absolute;
display: inline-block;
bottom: 0px;
width: 300px;
text-align: right;
transform: rotate(-90deg) translateY(100%);
border: 1px solid;
transform-origin: left bottom;
}
div, h1 {
margin: 0px;
padding: 0px;
}
<div>
<h1>Hola</h1>
</div>
Note to future visitors: Unlike using static values for positioning, this solution using translateY() would be able to adapt itself automatically even if the length of the content increases or spans multiple lines like in the below snippet. Again, the only drawback would be that the text would be right aligned.
div {
position: relative;
display: inline-block;
width: 250px;
height: 250px;
border: 1px solid black;
}
h1 {
position: absolute;
display: inline-block;
bottom: 0px;
width: 250px;
text-align: right;
transform: rotate(-90deg) translateY(100%);
border: 1px solid;
transform-origin: left bottom;
}
div,
h1 {
margin: 0px;
padding: 0px;
}
<div>
<h1>Halooo</h1>
</div>
<div>
<h1>Some lengthy content which wraps around</h1>
</div>
check this out it will give a direction to your required solution..
div {
width: 300px;
height: 300px;
border: 1px solid black;
}
h1 {
width: 70px;
margin-left: -20px;
float: left;
transform: rotate(-90deg)
}
<div>
<h1>Hola</h1>
</div>
Updated
Or you can do in this way also
div {
width: 300px;
height: 300px;
border: 1px solid black;
}
h1 {
position: absolute;
left: -10px;
top: 2px;
transform: rotate(-90deg)
}
<div>
<h1>Hola</h1>
</div>

Resources