How do I resize a div automatically to the size of its contents when the contents of the div have changed?

26,794

Solution 1

I've never used SimpleModal, but from the examples on their site it looks like you can set the container CSS. If you want the height to adjust, try setting the height to auto

$("#sample").modal({
  containerCss:{
    backgroundColor:"#fff",
    borderColor:"#0063dc",
    height:450,
    padding:0,
    width:830
  }
});

Although the example doesn't have it, I'd think you need to add px after the height and width in quotes (e.g. "450px").


Ok here is another idea. Maybe this is too much, but add a hidden input field:

<div id="myDiv">
  <form ...>
    Enter your name: <input id="txtYourName" type="text" name="YourName" value="" />
    <span id="errorYourName"></span>
    <input type="submit" ... />
    <input id="updated" type="hidden" />
  </form>
</div>

then attach a change event which is triggered at the same time you update the error message.

$(document).ready(function() {
  $("#txtYourName").live("blur", function() {
    if (validateInput($("#txtYourName").val())) {
      $("#errorYourName").html("");
      // entry 1
    } else {
      // entry 2
      $("#errorYourName").html("This name is not valid.");
      $("#updated").trigger('change');
    }
  });
  $("#updated").change(function(){
    // resize the modal window & reposition it
  })
});

This is untested and it may be going overboard, but I don't see an update function in SimpleModal.


Update : Sorry I figured out that blur isn't supported with live event. So I did some further testing and came up with a working demo. I posted it in this pastebin (ignore the included simpleModal code at the bottom). Here is the essential code

CSS

#myDiv { line-Height: 25px; }
#simplemodal-container { background-color:#444; border:8px solid #777; padding: 12px; }
.simplemodal-wrap { overflow: hidden !important; }
.error { color: #f00; display: none; }
input { float: right; }

HTML

<div id="myDiv">
  <form>
    What is your name: <input id="txtYourName" type="text" name="YourName" value="" /><br>
    <div id="errorYourName" class="error">This name isn't Arthur.</div>

    What is your quest: <input id="txtYourQuest" type="text" name="YourQuest" value="" /><br>
    <div id="errorYourQuest" class="error">This quest must be for the Grail.</div>

    What is your favorite color: <input id="txtYourColor" type="text" name="YourColor" value="" /><br>
    <div id="errorYourColor" class="error">Sorry, you must like red or blue.</div>

    What is the air speed velocity of an unladen swallow:<br>
    Type:
    <select>
     <option>African</option>
     <option>European</option>
    </select>
    <input id="txtYourGuess" type="text" name="YourGuess" value="" /><br>
    <div id="errorYourGuess" class="error">This guess stinks.</div>
    <hr>
    <input id="submitMe" type="submit" />
  </form>
</div>

Script

$(document).ready(function(){
  $("#myDiv").modal({
   containerCss:{
    height: '165px',
    width: '350px'
   }
 })
 $("#txtYourName").focus();

 addValidate('#txtYourName','Arthur','#errorYourName');
 addValidate('#txtYourQuest','Grail|grail','#errorYourQuest');
 addValidate('#txtYourColor','red|blue','#errorYourColor');
 addValidate('#txtYourGuess','11|24','#errorYourGuess'); // See http://www.style.org/unladenswallow/ ;)

  $("#myDiv form").change(function() {
   // This is called if there are any changes to the form... added here for an example
   // alert('Form change detected');
  });
})

function addValidate(el,valid,err){
 $(el).blur(function() {
  if ( $(el).val().length > 0 && !$(el).val().match(valid) ) {
   if ($(err).is(':hidden')) {
    $('#simplemodal-container').animate({'height': ($('#simplemodal-container').height() + 25) + 'px'},1000);
    $(err).slideDown(1000);
   }
  } else {
   // entry 2
   if ($(err).is(':visible')) {
    $('#simplemodal-container').animate({'height': ($('#simplemodal-container').height() - 25) + 'px'},1000);
    $(err).slideUp(1000);
   }
  }
 });
}

Solution 2

Jquery:

$(document).ready(function() {

var originalFontSize = 12;

var sectionWidth = $('#sidebar').width();



$('#sidebar span').each(function(){

    var spanWidth = $(this).width();

    var newFontSize = (sectionWidth/spanWidth) * originalFontSize;

    $(this).css({"font-size" : newFontSize, "line-height" : newFontSize/1.2 + "px"});

});

});

</script>

div:

<div id="sidebar">

<span>fits the width of the parent</span><br />

<span>Hello</span><br />

<span>my</span><br />

<span>name</span><br />

<span>is</span><br />

<span>john</span><br />

<span>1</span><br />

<span>23</span><br />

<span>456</span><br />

<span>12345678910</span><br />

<span>the font size in the span adjusts to the width</span><br />

</id>

preview http://jbdes.net/dev/js/fontsize.html

Solution 3

Old fashioned tables are (still) great at centering things, fast, fluid and code free.

<table width=100% height=100%><tr><td align=center valign=center>
    <table><tr><td style="yourStyle">
        your Content
    </td></tr></table>
</td></tr></tabĺe>

CSS: HTML,BODY {height:100%; width:100%}
Share:
26,794
Simon
Author by

Simon

I'm a front-end software developer for RTL Nederland, Hilversum, Netherlands.

Updated on June 20, 2020

Comments

  • Simon
    Simon almost 4 years

    At the moment, I have this DIV with a registration form centered over the page. The contents of the DIV come from an ascx-page. This is done nicely. Now, if the user tries to fill in a name that's not unique, an error message is added by some jQuery next to the username field. This breaks the layout of the DIV, since the contents now are wider than they used to be. So I've googled my way into this, but I can't find a solution for this.

    Can anyone help me find a nice way to do this (pseudo HTML/js):

    <div id="myCenteredDiv" onChangeContents="resizeToNewSize()">
      <!-- div contents -->
    </div>
    
    <script type="text/javascript">
      function resizeToNewSize() {
        $("#myCenteredDiv").animateToSize($("#myCenteredDiv").contentWidth, 
          $("#myCenteredDiv").contentHeight);
      }
    </script>
    

    I'm looking for the "onChangeContents" method (and/or event) and the "div.contentWidth" property.

    Thanks a lot for helping me out!

    update: trying to explain the problem more clearly

    Let's say I have this DIV:

    <div id="myDiv">
      <form ...>
        Enter your name: <input id="txtYourName" type="text" name="YourName" value="" />
        <span id="errorYourName"></span>
        <input type="submit" ... />
      </form>
    </div>
    

    And let's say I have this snippet of jQuery:

    $(document).ready(function() {
      $("#txtYourName").live("blur", function() {
        if (validateInput($("#txtYourName").val())) {
          $("#errorYourName").html("");
          // entry 1
        } else {
          // entry 2
          $("#errorYourName").html("This name is not valid.");
        }
      });
    });
    

    ...where validateInput(value) returns true for a valid value.

    Well now. The SimpleModal plugin takes the div and places it centered on the page, with a certain width and height it somehow reads off of the contents of the div. So the div isn't wider than the input box, since the span is empty at the moment.

    When the input box loses focus, an error message is put into the span. This then breaks the layout of the div.

    I could put code into entry 1 that resizes the div back with an animation to some size when the error message has been cleared, and code into entry 2 that resizes the div to a bigger size so the error message will fit.

    But what I'd like best is a way to tell if the contents within the div have changed, and fit the div accordingly, animated and automatically.

    Any ideas? Thanks again.

  • Simon
    Simon over 14 years
    I'll give that one a try. Thanks! I'll check back my result.
  • Simon
    Simon over 14 years
    Pity, it doesn't work. It only makes the border blue, and the div very large (Firebug tells me 'auto' is undefined...). I'll update the question and I'll try to make clearer what I want. But thanks anyway.
  • Simon
    Simon over 14 years
    Hopefully the question is more clear now. keeps fingers crossed
  • Simon
    Simon over 14 years
    Okay. So SimpleModal computes height/width of the div and puts those values in element.style as hard values (e.g. "width: 366.5"). What I do now, is put "width: auto !important" in my css file. The div doesn't break the layout when the contents are resized. Two things left to do: (1) animate the resizing, and (2) center the div on the page... (Why isn't "center: horizontal" part of the CSS standard? :-) )
  • Mottie
    Mottie over 14 years
    I know what you mean about centering, but the modal window has a fixed position, so you can't use something simple like margin: auto. So why did you set the width to auto and not the height, wasn't the height causing problems? height: auto !important. Is it necessary to animate it?
  • Simon
    Simon over 14 years
    Sorry, I wasn't complete. I did set height to auto too. I've tried "$("#myDiv").change(function() { resizeAndReposition() });" but that doesn't quite do the trick. I can't see how a hidden input will do that... I'll give it a try though. Thanks a lot!
  • Simon
    Simon over 14 years
    Oh and animations are a "could have". It just looks real nice: <code>function resizeModal(desiredWidth, desiredHeight, callback) { $.modal.impl.d.container.animate( { height: desiredHeight, width: desiredWidth, left: (window.innerWidth / 2) - (desiredWidth / 2), top: (((window.innerHeight / 2) - (desiredHeight / 2)) - 20) }, defaultTransitionDuration, defaultAnimationType, callback ); }</code>
  • Mottie
    Mottie over 14 years
    ok, I've posted a working demo here - it doesn't work perfectly in IE, but it's more working example that just needs a little tweeking (pastebin.me/b5c562cf996a553267b7d363daed662d)
  • Simon
    Simon over 14 years
    Wow, thanks a lot! I don't have my code with me here, but I'll try asap!