I have a problem with the heigth of the div.divB element in this code:
<div class="divA">
<img src="http://lorempixel.com/1000/130"/>
<div class="divB">
<span>Text text</span>
</div>
</div>
See this jsfiddle.
Why my is div.divB.height != div.divA.height? But his height is 100%.
I want it so that " text text " is in the middle.
EDIT:
Height image is random, because image file is uploading by User. In this example I use 130 but can be 200 or 50.
That is because you are declaring the height of the table to be 100px, which is 30px less than the height of the image. If you update that value to 130px, it should work as intended:
.divB{
display: table;
width: 100%;
height: 130px;
position: absolute;
top: 0px;
left: 0px;
}
See fiddle.
Alternatively, you might want to consider other approaches if your image element has a dynamic, non-static height. You can use (1) the translate by -50% approach, or (2) the flexbox approach.
For the translate by -50% approach, this works by simply forcibly stretching the parent container, .divB, to the size of its wrapping parent, by setting all four cardinal values to 0. After that, we position the inner child by 50% from the top, and then offset it vertically upwards by half of its height—that's when the translate by -50% trick kicks in:
.divB{
position: absolute;
top: 0px;
left: 0px;
bottom: 0px;
right: 0px;
}
.divB > span{
display: block;
transform: translateY(-50%);
padding-left: 120px;
position: absolute;
top: 50%;
font-size: 1.8rem;
color:white;
}
See alternative solution #1.
For the flexbox approach, we repeat the first step in the first solution—setting all cardinal offsets to 0—and then simply using the flexbox specification and align the inner element to the vertical center by using align-items: center:
.divB {
display: flex;
align-items: center;
position: absolute;
top: 0px;
left: 0px;
bottom: 0px;
right: 0px;
}
See alternative solution #2.
Firstly, divA is still set to block, so while it may have an image which is only 1000px wide, it will continue being wider than that image, setting the element to display: inline-block will help make sure that its widths are set fine.
Next, you need to set the height of divB to the same as divA. In this case its 130px.
You are also using padding for to centre the text, when you should really be using the text-align: center; ability.
Below is the full example
.divA {
position: relative;
display: inline-block;
overflow: auto;
}
.divB {
display: table;
width: 100%;
height: 130px;
position: absolute;
top: 0px;
left: 0px;
}
.divB > span {
display: table-cell;
vertical-align: middle;
text-align: center;
font-size: 1.8rem;
color: white;
}
<div class="divA">
<img src="http://lorempixel.com/1000/130" />
<div class="divB">
<span>Text text</span>
</div>
</div>
Related
I have a parent div that contains two children, side by side. The first child is an image that must be height 100% and 58% width, margin auto and overflow hidden. The second child contains text, and the length of the text determines the height of the parent. This is a template for several pages, with different length of text, and therefore different parent height. Is it possible to do what I'm trying to do without using JS? Thanks for your input! Code below.
HTML:
<div id="product-summary">
<div class="product-image-container">
<img />
</div>
<div id="product-details">
<h3 class="product-title"></h3>
<div class="product-description"></div>
</div>
</div>
CSS:
.product-image-container {
position: absolute;
top: 0;
left: 0;
width: 58%;
height: 100%;
overflow: hidden;
img {
position: absolute;
top: 0;
left: 50%;
margin: auto;
transform: translateX(-50%);
min-width: 100%;
height: 100%;
}
}
#product-details {
float: right;
border: solid thin #777;
height: ~"calc(100% - 2px)";
width: 41%;
text-align: center;
}
The problem is your #product-details is floated, which creates a new BFM (block formatting context), and the parent gets collapsed.
I suggest you read more about BFMs here: http://yuiblog.com/blog/2010/05/19/css-101-block-formatting-contexts/
There are several ways to fix this:
You could clear the parent, a way to do that is by adding overflow: hidden; to the #product-summary element.
You could remove the float: right from #product-details, and use flexbox to align it instead.
I don't know any preprocessor wizardry, but using inline-block works good, as well as keeping positioned absolute elements wrapped in a relative parent for control. It wasn't mentioned how the image is displayed, so I assume aspect ratio unchanged and no cropping.
SNIPPET
.product-image-container {
display: inline-block;
position: relative;
top: 0;
left: 0;
right: 0;
width: 58%;
height: 100vh;
overflow: hidden;
}
img {
display: inline-block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: auto;
}
#product-details {
float: right;
border: 1px solid #777;
height: 100%;
width: 41%;
text-align: center;
}
a {
margin-left: 50%;
}
<div id="product-summary">
<div class="product-image-container">
<img src='https://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png'>
</div>
<div id="product-details">
<h3 class="product-title">Lena Söderberg</h3>
<div class="product-description">
<blockquote>Lenna or Lena is the name given to a standard test image widely used in the field of image processing since 1973. It is a picture of Lena Söderberg, shot by photographer Dwight Hooker, cropped from the centerfold of the November 1972 issue of Playboy
magazine.
</blockquote>
<a href='https://en.wikipedia.org/wiki/Lenna'>Wikipedia</a>
</div>
</div>
</div>
What's the proper way to position an HTML element according to a center handle?
In this example:
XXXXXXXXX
|
|
123px
Assume the element should be position at absolute position left: 123px; but the text should be centered at that point, not start at it. The element text is dynamic, so I have no way of setting a static negative margin-left on it.
Is there a pure CSS way to achieve this? The JS way of measuring offsetWidth and then setting left after calculating width / 2 won't neccesarily work in my case due to various limitations.
One posibility is to set a transform translateX -50%
p {
position: relative;
display: inline-block;
left: 100px;
transform: translateX(-50%);
}
<p>ONE</p>
<br>
<p>TWO, LONGER</p>
<br>
<p>THREE, the longest</p>
It's fairly easy to achieve that and there are several ways to do it. Since you didn't post any HTML construct for your example, I'll just make up some.
The trick is to have an inline-block parent element which has the desired offset (123px) and inside that element you'll have another inline-block element with a left margin of -50%. Position both relative and you'll have the effect you are looking for.
#container {
position: relative;
}
#line {
width: 100px;
height: 100px;
left: 123px;
position: absolute;
border-left: 1px solid red;
}
#text {
left: 123px;
top: 50px;
display: inline-block;
position: relative;
}
#text p {
position: relative;
background: green;
margin-left: -50%;
display: inline-block;
color: #fff;
text-align: center;
padding: 10px;
box-sizing: border-box;
}
<div id="container">
<div id="line">
<-- 123px
</div>
<div id="text">
<p>
This is some dynamic text<br>the div has no absolute set width.
</p>
</div></div>
There are other ways as mentioned, probably depends on your general layout/HTML structure. I would definitely take a look at the flex-box properties, this might also be suitable here.
If you want to play around with it, here's a fiddle.
Some of various ways to do this with css:
If your element is a block:
.element{
width: 200px; /* Full width */
left: 50%;
margin-left: -100px; /* Half width */
position: absolute;
display: block;
}
or, if you're using css3:
.element{
width: 200px; /* Full width */
left: calc(50% - 100px);
position: absolute;
display: block;
}
You can also have a non-absolute approach, but the parent element position should be relative:
.element-parent{
position: relative;
}
.element-parent .element{
margin: 0 auto;
}
If you use text-oriented element (inline-block), this works with IE 7+:
.element-parent{
text-align: center;
}
.element-parent .element{
display: inline-block;
}
I'm trying to apply absolute position on an error label elemennt, which is inside an input field that is also positioned absolutely. The problem is that auto-width on the error element won't apply correctly, and will break after the first word. Why is that happening? If I use position right instead of left, it seems to work fine. Here's a jsfiddle link: http://jsfiddle.net/u793ata5/
Here's the HTML code:
<div id="outside">
<div id="inside">
<label class="error">Show this error on the side</label>
</div>
</div>
And CSS:
#outside {
position: relative;
width: 250px;
height: 250px;
}
#inside {
position: absolute;
top: 30%;
height: 30px;
left: 40%;
width: 80%;
}
.error {
width: auto;
position: absolute;
left: 90%;
top: 10%;
background-color: red;
color: white;
}
Why so many absolutely positioned elements? Maybe I'm not understanding what you want the layout to look like--and maybe you could clarify--but this modified fiddle looks more reasonable to me.
http://jsfiddle.net/u793ata5/3/
.error {
background-color: red;
display: block;
margin-left: 50%;
color: white;
}
I try not to use position: absolute unless I...uh absolutely have to.
You're putting it's position at 90% from the left. This means it only has 10% of the parent width to place text before wrapping. Try using
float: right;
instead of
left: 90%;
I'm trying to vertically center text inside a div that is positioned absolutely.
I have tried table-cell approach with no luck. This is a responsive layout, so I'm trying to avoid setting fixed heights and prefer not to use Javascript either.
Thanks
Link to jsbin demo
HTML & CSS:
<div class="page-banner" style="background: url(http://www.bimga.com.php53-3.ord1-1.websitetestlink.com//wp-content/uploads/BIMGA_Website_InteriorPage_Banners_About.jpg) no-repeat scroll 0 0 / cover transparent">
<img style="visibility:hidden" src="http://www.bimga.com.php53-3.ord1-1.websitetestlink.com//wp-content/uploads/BIMGA_Website_InteriorPage_Banners_About.jpg">
<div class="left">
<div class="page-banner-text">this text needs to be verticall centered</div>
</div>
</div>
<style type="text/css">
.page-banner {
margin-bottom: 35px;
list-style: none;
width: 100%;
padding-left: 0;
position: relative;
}
.page-banner img {
width: 100%;
height: auto;
}
.page-banner .left {
background-color: rgba(10, 65, 142, .75);
position: absolute;
z-index: 1;
left: 0;
top: 0;
height: 100%;
text-align: center;
width: 50%;
}
</style>
We could use a transform like so:
Have a jsBin!
CSS
.page-banner-text {
top: 50%;
transform: translateY(-50%);
position: absolute;
}
More information on this technique.
What you can do is, set the text position to absolute.
Then give it a top: 50%; and give it a top margin of minus half its height.
I would not prefer using position absolute and top: 50% for better multi browser support (espesially on older IE versions) so I would prefer adding line-height: x em; in your .page banner class. Em because you have defined the height by % so it needs to always be on the center no matter the actual pixel height.
.page-banner .left:after {
content: "Background text";
position: absolute;
top: 40%;
left: 35%;
z-index: -1;
}
I want to set the gemoetrical center of my div block at the geometrical center of the screen. How i can do that? Let we have
<div style="position: absolute; width: 240px; height: 150px; margin:50%; >
some content
</div>
But it doesn't work. I dont undestand why it doesnt. margin:50% equivalent to margin-top/left/right/bottom: 50%. Thus we have extra space to our div element as 50% of linear screen size. Why it is neccesary to define the width and height explicitly if we use margin attribute or top/left/right/bottom attributes?
Here we go. The HTML:
<body>
<div class="centered">Hello</div>
</body>
The CSS:
.centered {
position: absolute;
width: 240px;
height: 150px;
/* positioning the element (top/left corner) at the center */
top: 50%;
left: 50%;
/* moving the element's center to the screen's center (compensating relatively to the dimensions) */
margin-top: -75px; /* half of the height */
margin-left: -120px; /* half of the width */
}
margin: 50% won't work because of elements with position: absolute lose the reference to the parent's dimensions. This is one of the various layout problems with the CSS Box Model.
However, you can use the Flexbox Layout Model, that would be a lot easier:
body {
display: flex;
}
.centered {
margin: auto;
}
You just need to set margin: auto and the parent element must be set as display: flex. Simple =)
We can use the following:
<div style="position: absolute; margin: auto; width: 240px; height: 150px; top: 0; left: 0; bottom: 0; right: 0;">
some content
</div>
Use the below to make it centralized.
For Instance,
<div style="display: table; margin: 0px auto;">
<div style="margin: 0px auto; text-align: center; background: none repeat scroll 0% 0% gray; width: 240px; height: 150px; display: table-cell; vertical-align: middle;">
some content
</div>
</div>
WORKING DEMO
Hope this helps.