How to Set an Element's Size to Fit Its Potential Content, Rather Than Its Actual Content

Can I set an element's size to fit its potential content, rather than its actual content?

I would consider data attribute to add both texts using pseudo elements then control the opacity to hide/show them:

div {

text-align: right;

}

#del {

display: inline-block;

position: relative

}

#del:before {

content: attr(data-text);

position:absolute;

left:0;

right:0;

top:1px; /*there is 1px default padding */

text-align:center;

}

#del:after {

content: attr(data-alt);

opacity:0;

}

#del:hover::before {

opacity:0;

}

#del:hover::after {

opacity:1;

}
<div><button>Save</button><button>Cancel</button><button data-text="Delete" data-alt="Click me again to confirm deletion" id="del"></button></div>

make div's height expand with its content

You need to force a clear:both before the #main_content div is closed. I would probably move the <br class="clear" />; into the #main_content div and set the CSS to be:

.clear { clear: both; }

Update: This question still gets a fair amount of traffic, so I wanted to update the answer with a modern alternative using a new layout mode in CSS3 called Flexible boxes or Flexbox:

body {

margin: 0;

}

.flex-container {

display: flex;

flex-direction: column;

min-height: 100vh;

}

header {

background-color: #3F51B5;

color: #fff;

}

section.content {

flex: 1;

}

footer {

background-color: #FFC107;

color: #333;

}
<div class="flex-container">

<header>

<h1>

Header

</h1>

</header>

<section class="content">

Content

</section>

<footer>

<h4>

Footer

</h4>

</footer>

</div>

Div expand to size of certain content

So the answer to both of these questions, it seems, is that you cannot do this without javascript. The reason being that the CSS box model just does not work in this way.

In order to solve just the first problem you need to use absolute positioning like I tried but then use javascript to create a space for the element using a margin on the h1, something like this:

$(document).ready(function() {
function alignDescriptions() {
var pmargin = 10 * 2;
$('.abs').each(function() {
var pheight = $(this).height();
$(this).css('bottom', pmargin);
$(this).siblings('h1').css('margin-bottom', pheight + pmargin);
});
}
});

That solves the vertical centering issue when using absolute so problem 1 is fixed.

To solve the second problem, the following answer provides one solution: https://stackoverflow.com/a/33246364/7542390

I believe simply using this but also using the width of the span as a minimum would probably solve both problems as I would be literally forcing the width to the correct size so having a 75% width p element wouldn't be a problem.

It's a shame that this kind of functionality isn't in the CSS spec.

EDIT: As suspected, an adaption of the second option actually removes the need for absolute positioning of the p element. Here's the jQuery code that worked for my actual case:

$('h1').each(function() {
// references to elements
var hElem = $(this);
var pElem = hElem.siblings('p');
var sElem = hElem.siblings('span');
// store starting values
var sWidth = sElem.width();
var hHeight = hElem.height();
var hWidth = hElem.width();
// reduce width until less than span width
// or until height of h1 changes
for (var testWidth = hWidth - 1; testWidth > 0; testWidth--) {
if (testWidth <= sWidth) {
testWidth = sWidth - 1;
break;
}
hElem.width(testWidth);
if (hElem.height() !== hHeight) break;
}
// set h1 width
hElem.width(++testWidth);
// if h1 still overflows (long word) use that instead
if (hElem[0].scrollWidth > hElem.width()) {
testWidth = hElem[0].scrollWidth;
hElem.width(testWidth);
}
// set p element to 75% width
pElem.width(testWidth * 0.75);
});

Width equal to content

By default p tags are block elements, which means they take 100% of the parent width.

You can change their display property with:

#container p {
display:inline-block;
}

But it puts the elements side by side.

To keep each element on its own line you can use:

#container p {
clear:both;
float:left;
}

(If you use float and need to clear after floated elements, see this link for different techniques: http://css-tricks.com/all-about-floats/)

Demo: http://jsfiddle.net/CvJ3W/5/

Edit

If you go for the solution with display:inline-block but want to keep each item in one line, you can just add a <br> tag after each one:

<div id="container">
<p>Sample Text 1</p><br/>
<p>Sample Text 2</p><br/>
<p>Sample Text 3</p><br/>
</div>

New demo: http://jsfiddle.net/CvJ3W/7/

Adjust width of input field to its input

It sounds like your expectation is that the style be applied dynamically to the width of the textbox based on the contents of the textbox. If so you will need some js to run on textbox contents changing, something like this:

<input id="txt" type="text" onkeypress="this.style.width = ((this.value.length + 1) * 8) + 'px';">

Note: this solution only works when every character is exactly 8px wide. You could use the CSS-Unit "ch" (characters) which represents the width of the character "0" in the chosen font. You can read about it here.

Maintain the aspect ratio of a div with CSS

Just create a wrapper <div> with a percentage value for padding-bottom, like this:

.demoWrapper {
padding: 10px;
background: white;
box-sizing: border-box;
resize: horizontal;
border: 1px dashed;
overflow: auto;
max-width: 100%;
height: calc(100vh - 16px);
}

div {
width: 100%;
padding-bottom: 75%;
background: gold; /** <-- For the demo **/
}
<div class="demoWrapper">
<div></div>
</div>

How to do overflow of content div without specifying pixel height

I think that I found the solution. The last bit was to do min-height on the footer. No need to specify growth as only the content div is suppose to grow in this example.

body {
margin: 0;
padding: 0;## Heading ##
height: 100vh;
}
main, footer {
color: #ffffff;
}

main {
background: #000000;
display: flex;
flex-direction: column;
max-height: 100vh;
}

.main {
overflow: auto;
}

.content {
background: blue;
overflow-y: auto;
height: auto;
}
.footer {
background: #616161;
min-height: 100px;
width: 100%;

}
.boxes {
background-color: yellow;
width: 95%;
height: 250px;
margin: 5px;
}
<main>
Main
<div class="main">
<section class="content">
<div class="boxes">1</div>
<div class="boxes">2</div>
<div class="boxes">3</div>
</section>
</div>
<footer class="footer">Footer</footer>
</main>


Related Topics



Leave a reply



Submit