Preventing a div from expanding the width of a parent table - html

I am working on a project where I will be injecting markup into pages I don't have control over (an embed script). An interesting case has come up where my injected div is contained within a table. A child of my div is a horizontal menu that should scroll (overflow-x: auto) when it exceeds the width of the parent element, but in the case where a parent element is a table without table-layout: fixed, my injected content instead causes the parent table to expand, horribly breaking some layouts.
In this case, the table is contained within a fixed-width div, something like this:
<div style="width: 600px;">
<table width="100%">
<tr>
<td>
<div> <!-- my content --> </div>
</td>
</tr>
</table>
</div>
I found that setting table-layout: fixed on the table fixes this problem. However, this markup is beyond my control -- I can only change markup/CSS starting from the innermost div.
I did find one hack that works: setting width: 100%; display: table; table-layout: fixed; on my div. However, I'm not sure if this is compliant with any relevant specs, as the contents of this display: table div are all display: block.
Here is markup that reproduces the problem, as well as demonstrates the hack:
<div class="outer">
<table class="bad-table">
<tr>
<td>
<div class="wrapper">
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam imperdiet pharetra nunc at condimentum.</div>
<div class="target">
<ul class="menu">
<li style="background-color: #800;"></li>
<li style="background-color: #880;"></li>
<li style="background-color: #080;"></li>
<li style="background-color: #008;"></li>
</ul>
</div>
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam imperdiet pharetra nunc at condimentum.</div>
</div>
</td>
</tr>
</table>
</div>
<div class="outer">
<table class="bad-table">
<tr>
<td>
<div class="wrapper hack">
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam imperdiet pharetra nunc at condimentum.</div>
<div class="target">
<ul class="menu">
<li style="background-color: #800;"></li>
<li style="background-color: #880;"></li>
<li style="background-color: #080;"></li>
<li style="background-color: #008;"></li>
</ul>
</div>
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam imperdiet pharetra nunc at condimentum.</div>
</div>
</td>
</tr>
</table>
</div>
CSS:
.outer {
width: 200px;
border: 1px solid #0f0;
}
.bad-table {
width: 100%;
border: 1px solid #f00;
}
.target {
width: 100%;
overflow-x: auto;
overflow-y: hidden;
}
.wrapper {
width: 100%;
}
.wrapper.hack {
display: table;
table-layout: fixed;
}
ul.menu {
list-style: none;
padding: 0;
margin: 0;
white-space: nowrap;
width: 100%;
}
ul.menu li {
display: inline-block;
width: 100px;
height: 50px;
padding: 0;
margin: 0;
}
(Fiddle)
Note that in the first example, the menu blocks cause the table (red border) to expand beyond its containing div (green border). Compare to the second example, which uses my (standards-violating?) hack that successfully prevents the parent table from growing, while also allowing the menu blocks to be scrolled. (Tested with Chrome and Firefox.)
Note the following constraints:
I absolutely cannot edit the markup outside of my injected div. This includes manipulating the DOM outside of my injected div, because I don't know what bad effects my changes to someone else's document might cause.
The height of my injected div should be based on its contents (as per normal document flow) which means that solutions using position: absolute will tend to be problematic as they will remove my content from the page flow, making preceding and/or following content overlap the injected div. The usual fix for this (setting a fixed height) means my element will be unable to fit its height to match its contents.
Is this hack a legitimate way to solve this problem, or is there a better approach?

table's is always tricky but I have used position: absolute with success in many situations, so my answer/question will be: Will this work for you?
Note though, the wrapper is just a wrapper and should only contain the target, so all content goes into the target, or else the target will overlap its siblings, unless fixed margins/paddings is set.
.outer {
width: 200px;
}
.bad-table {
width: 100%;
}
.wrapper {
position: relative;
}
.target {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: auto;
overflow: auto;
}
ul.menu {
list-style: none;
table-layout: fixed;
padding: 0;
margin: 0;
white-space: nowrap;
width: 100%;
}
ul.menu li {
display: inline-block;
width: 100px;
height: 50px;
padding: 0;
margin: 0;
}
<div class="outer">
<table class="bad-table">
<tr>
<td>
<div class="wrapper">
<div class="target">
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam imperdiet pharetra nunc at condimentum.</div>
<ul class="menu">
<li style="background-color: #800;"></li>
<li style="background-color: #880;"></li>
<li style="background-color: #080;"></li>
<li style="background-color: #008;"></li>
</ul>
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam imperdiet pharetra nunc at condimentum.</div>
</div>
</div>
</td>
</tr>
</table>
</div>
For comparison, here is the same code snippet using display: table
.outer {
width: 200px;
}
.bad-table {
width: 100%;
}
.wrapper {
width: 100%;
display: table;
table-layout: fixed;
}
.target {
overflow: auto;
}
ul.menu {
list-style: none;
table-layout: fixed;
padding: 0;
margin: 0;
white-space: nowrap;
width: 100%;
}
ul.menu li {
display: inline-block;
width: 100px;
height: 50px;
padding: 0;
margin: 0;
}
<div class="outer">
<table class="bad-table">
<tr>
<td>
<div class="wrapper">
<div class="target">
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam imperdiet pharetra nunc at condimentum.</div>
<ul class="menu">
<li style="background-color: #800;"></li>
<li style="background-color: #880;"></li>
<li style="background-color: #080;"></li>
<li style="background-color: #008;"></li>
</ul>
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam imperdiet pharetra nunc at condimentum.</div>
</div>
</div>
</td>
</tr>
</table>
</div>
Update
After some more testing, and reading these,
https://www.w3.org/TR/CSS2/tables.html#anonymous-boxes
Is a DIV inside a TD a bad idea?
I can't find any other way to solve this case, so if there will be content before and after the uncontrolled outer div/table to which your content div's content need to have a normal flow, position: absolute might not work depending how the rest of the page's content is set, but display: table; table-layout: fixed will.
And according to the above sources, there shouldn't be any compliance issues using display: table1, though you need to test the behavior in the major browsers, as they all might deal with div's inside td's different (I did test Chrome,FF,Edge,IE11 on Windows, all worked).
1 Specifically, this text allows for a display: block element directly inside of a display: table element, as the intermediate table-row and table-cell boxes are automatically created as anonymous:
Generate missing child wrappers:
If a child C of a 'table' or 'inline-table' box is not a proper table child, then generate an anonymous 'table-row' box around C and all consecutive siblings of C that are not proper table children.
If a child C of a row group box is not a 'table-row' box, then generate an anonymous 'table-row' box around C and all consecutive siblings of C that are not 'table-row' boxes.
If a child C of a 'table-row' box is not a 'table-cell', then generate an anonymous 'table-cell' box around C and all consecutive siblings of C that are not 'table-cell' boxes.

It's possible to scale an element to its parent's width if that is a table cell, but you will have to workaround some negative consequences. Consider this:
<style>
table {
border-collapse: collapse;
width: 100%;
}
td {
border: 1px solid gray;
padding: 20px;
}
.prevent-table-expand-wrap {
position: relative;
}
.prevent-table-expand-inner {
/* Add ellipsis. */
overflow-x: hidden;
text-overflow: ellipsis;
white-space: nowrap;
/* Make div the width of its parent. */
position: absolute;
left: 0;
right: 0;
bottom: 0;
}
</style>
<table>
<tr><td>
Column 1.
</td><td>
Column 2.
<div class="prevent-table-expand-wrap">
<div class="prevent-table-expand-inner" title="This contains way too much text, so prevent scaling table">
Lots of text. Lots of text. Lots of text. Lots of text. Lots of text. Lots of text. Lots of text. Lots of text. Lots of text. Lots of text. Lots of text. Lots of text. Lots of text. Lots of text. Lots of text. Lots of text. Lots of text. Lots of text. Lots of text. Lots of text. Lots of text. Lots of text. Lots of text. Lots of text. Lots of text. Lots of text. Lots of text. Lots of text. Lots of text. Lots of text.
</div>
</div>
</td><td>
Column 3.
</td></tr>
</table>
https://jsfiddle.net/zgwmLms1/19/
The way this works is that the wrapper div just gets width 100% of its container, the table cell. It doesn't have content that affects the scaling of the table columns (well, the nbsp is too narrow). The inner div then gets absolutely positioned and constrained to the wrapper on three sides. Might as well do all 4 sides, but it's not necessary to do both the top and bottom explicitly in this case, as the height of the wrapper and inner are the same.
The biggest difference with the other answer is that mine combines content that does influence the column width, and content that doesn't, in the same table cell. You can see that all 3 columns are evenly sized, that is due to the Column n text.

Potentially try display: inline-block on the div you want to shrink. It worked for me just now.

Related

Vertically align text in contenteditable div in td where the div is same size as td

I have a td with a div with some text. The div shall have 100% of the height and width of the td, and the text shall be centered both vertically and horizontally. I sometimes want to format the text in the div using spans, and it can happen that the text is too long so it will be in multiple lines.
I tried using a flexbox, but that made the text make line breaks whenever there was a span. Also tried to put the div in a div, and only use the flexbox on the parent div, but that also didn't work. I've also tried to set the div to "display: table-cell", but this made the div not able to fill the entire cell. So now I really don't know what to try.
Table cell:
td {
border: 1px solid #d9d9d9;
height: 16pt;
padding: 0;
min-width: 100px;
}
Div with text in the cell:
.cellText {
height: 100%;
text-align: center;
vertical-align: middle;
}
Add the following lines of code to your .cellText CSS class:
display: flex;
align-items: center;
justify-content: center;
Then add a div element inside your .cellText instances and put your text content there.
Example
td {
border: 1px solid #d9d9d9;
height: 16pt;
padding: 0;
min-width: 100px;
}
.cellText {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
text-align: center;
vertical-align: middle;
}
/* For testing purposes */
td {
width: 500px;
height: 150px;
}
<table style="width:350px">
<tr>
<th>Title</th>
<th>Title</th>
</tr>
<tr>
<td>
<div class="cellText">
<div>
<span>First span</span> <span>Second span</span> <span>Third span</span> <span>Fourth span</span>
</div>
</div>
</td>
<td>
<div class="cellText">
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit..
</div>
</div>
</td>
</tr>
<tr>
<td>
<div class="cellText">
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum commodo, purus ac vestibulum dapibus.
</div>
</div>
</td>
<td>
<div class="cellText">
<div>
Lorem ipsum dolor sit amet.
</div>
</div>
</td>
</tr>
</table>

CSS: two side-by-side p tags, same height, left one fixed-width & known height

I'm trying to get a vertical list of <li>'s of varying height, where each has two <p> tags next to each other and has a height of the tallest <p> tag; the <p> on the left has a fixed width (128px) and the <p> on the right should take up the rest of the page but not wrap underneath the first <p>.
Here's sample HTML:
<ul>
<li> <!-- height = the tallest of the two p tags -->
<p class="category">Something (128px wide)</p>
<p class="description">Something long...
Shouldn't wrap underneath .category
</p>
</li>
<li> <!-- beneath the li above, probably different height -->
<p class="category">Another thing</p>
<p class="description">Another long description...</p>
</li>
</ul>
What should the CSS look like?
Flexbox can do the trick for you.
ul {
width: 300px;
}
li {
width: 100%;
clear: both;
display: flex;
flex-direction: row;
}
li p {
display: inline;
float: left;
background-color: #eeeeee;
}
p.category {
width: 128px;
}
<ul>
<li>
<!-- height = the tallest of the two p tags --->
<p class="category">Something (known width)</p>
<p class="description">Something long... Shouldn't wrap underneath .category
</p>
</li>
<li>
<!-- beneath the li above, probably different height -->
<p class="category">Another thing</p>
<p class="description">Another long description...</p>
</li>
</ul>
More Info:
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
There are several ways to skin this cat. If I'm understanding what you're after correctly, I think that using table-row and table-cell display properties may be the easiest way to go.
Here's a jsfiddle:
https://jsfiddle.net/s2jzh31z/2/
That includes the following,
HTML:
<ul>
<li>
<p class="category">Something (known width)</p>
<p class="description">Something long and multiple lines.
Shouldn't wrap underneath category.
Lorem ipsum dolor sit amet consecteur adipiscing elit no numi.
Lorem ipsum dolor sit amet consecteur adipiscing elit no numi.
Lorem ipsum dolor sit amet consecteur adipiscing elit no numi.
Lorem ipsum dolor sit amet consecteur adipiscing elit no numi.
Lorem ipsum dolor sit amet consecteur adipiscing elit no numi.
Lorem ipsum dolor sit amet consecteur adipiscing elit no numi.</p>
</li>
<li>
<p class="category">Another thing(known width)</p>
<p class="description">Something to the right,
determines the height of this "<li>"</p>
</li>
</ul>
CSS:
ul {
margin: 0;
}
li {
clear: both;
display: table-row;
width: 100%;
}
p {
display: table-cell;
padding: .5em;
vertical-align: top;
}
p.category {
width: 128px;
}
I took the liberty of vertical aligning and adjusting the padding a bit to make it look neater. The vertical align was one of the benefits I was looking for in using the table-row / table-cell approach.
To be semantically correct and 'new age' you could do this using CSS3's Flexbox layout but if this is table data (looks to be, using category and description) then you could restructure it as a table (which also helps if you need to support older browsers).
HTML would look like this:
<table>
<tr>
<td class="category">Something (known width)</td>
<td>Something long and multiple lines.sdsdsdsdsdsdsdsdsdsdsdsdddddddddddddddddddddddddddddddsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsssssssssssssssssssssssssssssdddddddddddddddddddddddsdssdsssssssssssssssssssssssssss
Shouldn't wrap underneath .category</td>
</tr>
<tr>
<td class="category">Another (known width)</td>
<td>Another long and multiple lines.
Shouldn't wrap underneath .category</td> </tr>
</table>
and your CSS:
.category {
width: 128px;
}

CSS for a text container between min and max width

How can I style a DIV with text in it so that if takes the minimum length between a min-width and a max-width?
For example, if I have the min and max set at 200 and 400px, I want:
a div with text shorter than 200px to be 200px wide
a div with text between 200px and 400px to have the width of the text
a div with text longer than 400px to be wrapped
This jsFiddle I made explains it better: http://jsfiddle.net/LHFSn/ ...it sounds simple and straight forward but I just can't seem to figure it out.
And no, the obvious:
min-width: 200px;
max-width: 400px;
...doesn't give me what I want at all.
Setting
display: inline-block
will allow you to achieve the desired result width-wise, but will also mean the elements will be displayed inline, that is, next to one another if they fit.
You can avoid this by wrapping your elements in block-style containers. While this sounds far from ideal it's the first idea off the top of my head that works.
Expanding on your further question, you can float these elements, wrap them in a container that's also displayed inline and then block it using RĂșnar Berg's suggestion of empty blocks.
See sample jsFiddle
Clearfix reference
HTML:
ACTUAL:
<div></div>
<div class="wrapper cf">
<div class="flex-text">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor.
</div>
<div class="flex-text">
Lorem ipsum dolor sit amet.
</div>
<div class="flex-text">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
</div>
</div>
<div></div>
Further content
CSS:
.flex-text {
min-width: 200px;
max-width: 400px;
display: inline-block;
background: #def;
float: left;
clear: both;
}
/* this is just to show a 200px ruler for reference */
.flex-text:after {
content: "";
display: block;
width: 200px;
border-top: 4px solid black;
margin: 0 0 20px 0;
}
.wrapper {
display: inline-block;
background: lightblue;
}
.cf:before,
.cf:after {
content: " "; /* 1 */
display: table; /* 2 */
}
.cf:after {
clear: both;
}
.cf {
*zoom: 1;
}
You can try to set the container display to table and the inner display to table-cell.
It might get you into more trouble though.
http://jsfiddle.net/fXxV3/3/
Problem:
Your .flex-text is a non-floated block element so by default it fills the width of its parent. In this case, max-width means if your parent is larger then take on the max-width and if your parent is smaller than min-width then take that value.
On the other hand, a floated block element with no width set will shrink to the size of its contents.
Solution:
You basically have to move your min/max width to an outer wrapper div which is not floated as you did, and then float the inner flex-text inside so that the background will only fill the area containing text:
So your markup becomes:
<div class="wrapper">
<div class="flex-text clearfix">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor.
</div>
</div>
<div class="wrapper">
<div class="flex-text clearfix">
Lorem ipsum dolor sit amet.
</div>
</div>
<div class="wrapper">
<div class="flex-text clearfix">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
</div>
</div>
So your css becomes:
.wrapper{
min-width: 200px;
max-width: 400px;
}
.flex-text {
background: #def;
float:left;
}
Also, since you are floating .flex-text, make sure to add a clearfix.
DEMO

How do I keep floated elements flopping down without using a fixed width?

I am styling a series of form rows. Each row div has a fixed-width label div, and a content div that can contain any number of float: left elements.
Example markup is:
<div class="Row">
<div class="Label">Label Here</div>
<div class="Content">
<div class="Item">Short Content</div>
</div>
</div>
<div class="Row">
<div class="Label">Label Here</div>
<div class="Content">
<div class="Item">
Long Content ... Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris id eros magna. Suspendisse eu diam nunc. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce eu neque massa.
</div>
</div>
</div>
CSS so far is:
.Row {
clear: left;
padding: 10px;
}
.Label {
float: left;
width: 150px;
}
.Content {
float: left;
}
.Content .Item {
float: left;
}
jsfiddle here: http://jsfiddle.net/vVy5J/2/
This looks correct as long as the contents of the content div are not wider than the remaining width in the row. If they are, the content div 'flops' down beneath the label instead and hugs the left edge of the row div: http://screencast.com/t/Iknv98R9
I need long content divs to wrap, but still be against the top of the row and flush with the right edge of the label.
The traditional solution for this is to give the content div a fixed width. But that won't fly here because the row widths vary based on browser window size, etc. and the content div needs to stretch from the right edge of the label div to the right edge of the containing row div.
Requirements: I can alter the markup only within the row div. Contents need to be elements, so text-indent won't work for me. I need to support IE7+
You could put a position:relative; on the Row, position:absolute; on the Label just to take it out of the document flow, then margin-left:150px on the Content (or however wide it's supposed to be).
It won't be good though if there's any chance of the Label being taller than the Content.
You can use simple positioning trick. #row must be relative and content is absolute with left: 150px.
.Row
{
...
position: relative;
}
.Content
{
...
position: absolute;
left: 150px;
}
jsfiddle

Text Wrapping around an absolute positioned div

I know there are a few questions about similar topics but they mostly amount to floating the div/image. I need to have the image (and div) positioned absolutely (off to the right) but I simply want the text flow around it. It works if I float the div but then I can't position it where I want. As it is the text just flows behind the picture.
<div class="post">
<div class="picture">
<a href="/user/1" title="View user profile.">
<img src="http://www.neatktp.com/sites/default/files/photos/BlankPortrait.jpg" alt="neatktp's picture" title="neatktp's picture" />
</a>
</div>
<span class='print-link'></span>
<p>BlahBlahBlahBlahBlahBlahBlahBlahBlahBlahBlahBlahBlahBlahBlah.</p>
<p>BlahBlahBlahBlahBlahBlahBlahBlahBlahBlahBlahBlahBlahBlahBlah.</p>
</div>
Is an example of the HTML
With the CSS being:
.picture img {
background: #fff;
border: 1px #ddd solid;
padding: 2px;
float: right;
}
.post .picture {
display: block;
height: auto;
position: absolute;
right: -10px;
top: -10px;
width: auto;
}
.post {
border: 1px solid #FFF;
border-bottom: 1px solid #e8ebec;
padding: 37px 22px 11px;
position: relative;
z-index: 4;
}
It's a Drupal theme so none of this code is mine, it's just that it's not fully working when it comes to putting a picture there.
I know this is an older question but I came across it looking to do what I believe you were trying to. I've made a solution using the :before CSS selector, so it's not great with ie6-7 but everywhere else you should be good.
Basically, putting my image in a div I can then add a long thing float block before hand to bump it down and the text wraps merrily around it!
img {
float:right;
clear:both;
width: 50% ;
margin: 30px -50px 10px 10px ;
}
.rightimage:before {
content: '' ;
display:block;
float: right;
height: 200px;
}
You can check it out here:
http://codepen.io/atomworks/pen/algcz
Absolute positioning takes the element out of the normal document flow, and therefore it does not interact with the other elements. Perhaps you should revist how to position it using float instead, and ask about it here on Stack Overflow if you get stuck :)
As mentioned by #Kyle Sevenoaks, you are taking absolute positioned content out of the document flow.
As far as I can see, the only way to have the parent div wrap the absolute positioned contents, is to use javascript to set the width and height on each change.
When you position a div absolutely, you're effectively taking it out of the document flow, so the other elements will act as if it's not there.
To get around this, you can instead use margins:
.myDivparent
{
float: left;
background: #f00;
}
.myDivhascontent
{
margin-left: 10px; /*right, bottom, top, whichever you need*/
}
Hopefully that will do the trick :)
In my opinon, the "Absolute" trait is poorly named, because its position is actually relative to the first parent whos position is not static
<div class="floated">
<div style="position: relative;">
<div class="AbsoluteContent">
stuff
</div>
</div>
</div>
I think the best option is to add an additional div after the float content, but still inside the parent to clear previous styles.
<div class="clear"></div>
And CSS:
.clear
{clear:both;}
I needed a similar solution to float a pullout quote (not an image) which would have variable length text inside. The pullout quote needed to be inserted into the HTML at the top (outside the flow of the text) and float down into the content with text that wraps around it. Modifying Leonard's answer above, there is a really simple way to do this!
See Codepen for Working Example: https://codepen.io/chadwickmeyer/pen/gqqqNE
CSS
/* This creates a space to insert the pullout content into the flow of the text that follows */
.pulloutContainer:before {
content: '' ;
display:block;
float: right;
/* The height is essentially a "margin-top" to push the pullout Container down page */
height: 200px;
}
.pulloutContainer q {
float:left;
clear:both;
/* This can be a set width or percent, if you want a pullout that floats left or right or full full width */
width: 30%;
/* Add padding as you see fit */
padding: 50px 20px;
}
HTML
<div id="container">
<div class="pulloutContainer">
<!-- Pullout Container Automatically Adjusts Size -->
<q>Lorem ipsum dolor sit amet, consectetur adipiscing elit Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet, consectetur adipiscing elit Lorem ipsum dolor sit amet.</q>
</div>
<div class="content">
<h1>Sed Aucteor Neque</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam in dui mauris. Vivamus hendrerit arcu sed erat molestie vehicula. Sed auctor neque eu tellus rhoncus ut eleifend nibh porttitor. Ut in nulla enim. Phasellus molestie magna non est.</
...INSERT MORE TEXT HERE...
</div>
</div>
Absolute positioning does not let you wrap text. You have to use float and position using margin or padding.
Here's a trick that might work for some:
if you have a container packed with a lot of objects, and you want that positioned object to appear up high in certain cases, and down lower in other cases (various screen sizes for example), then just intersperse copies of the object multiple times in your html, either inline(-block), or with float, and then display:none the items you dont want to see according to the conditions you need.
Here is a JSFiddle to show exactly what I mean: JSFiddle of right positioning high and low
Note: I added color only for effect. Except for the class names, the subject-1 and subject-2 divs are otherwise exact copies of each other.
There is an easy fix to this problem. It's using white-space: nowrap;
<div style="position:relative">
<div style="position: absolute;top: 100%; left:0;">
<div style="white-space:nowrap; width: 100%;">
stuff
</div>
</div>
</div>
For example I was making a dropdown menu for a navigation so the setup I was using is
<ul class="submenu" style="position:absolute; z-index:99;">
<li style="width:100%; display:block;">
Dropdown link here
</li>
<ul>
Image Examples
Without Nowrap enabled
With Nowrap enabled
Also if you still can't figure it out check out the dropdowns on bootstrap templates which you can google. Then find out how they work because they are using position absolute and getting the text to take up 100% width without wrapping the text.