Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 5 of 5
  1. #1
    Regular Coder
    Join Date
    May 2007
    Posts
    104
    Thanks
    19
    Thanked 12 Times in 12 Posts

    Using em to size div to same height as a few lines of text

    I am making a list of items which when first displayed will appear truncated but will have a button to click to expand to make the full list visible. Initially only the first three items in the list will be visible. I am using a DIV with a set height and a overflow:hidden to hide items which appear further down the list.

    I figure that setting the height of the DIV using em units is the best approach because these units are relative to the size of the text being used, so if larger text is used in some lists then more space will be made to accommodate the larger text (rather than specifying the height in pixels which would require an adjustment of the numerical value in the code if the text size changes).

    My problem though is that em units don't seem to include the additional space that goes between lines of text. If I use an em value of 3 then only about 2.5 lines of text are displayed.

    Is there a way I can size the DIV to the exact same height of three lines of text without having to use a pixel value?

  • #2
    New Coder
    Join Date
    Sep 2012
    Location
    Scottish Borders
    Posts
    36
    Thanks
    1
    Thanked 9 Times in 9 Posts
    Hi, trying to visualise what you are trying to do and if reading it correctly the answer will be mathematical. If you give your list items an em font size, a line height value and a margin value then assuming that the list items are not long enough to wrap the div value should be three times the individual list item inclusive value.
    Code:
    li{font-size:1em;line-height:1.5em;margin:0.5em;}
    would give an individual height of 2.5em and with the proviso that the ul had no values of it's own and that the parent element of the div that you are using had the same values the div would require to be 7.5em. Hope this makes some sort of sense. Jim
    Jims Way is following a strict but simple code

  • Users who have thanked jamaks for this post:

    >ssp-cdr< (10-17-2012)

  • #3
    Senior Coder Rowsdower!'s Avatar
    Join Date
    Oct 2008
    Location
    Some say it's everything.
    Posts
    2,027
    Thanks
    5
    Thanked 397 Times in 390 Posts
    If I understand you correctly, either you will be using this module in places that have a static font size for all items in their list, but which may use a different font size than other places in which the module is used - or your parent div will have three items to display, each with a possibly different font size. I'm not too concerned with which it is because I think your em units are failing for the same reason either way. The em units for the container/parent div are going to be based on its specified font size or its inherited font size...not on the font sizes of any child elements it contains.

    So, if your list items will all have the same size font in any given instance of this module, then I'll assume jamaks' code handles it (I haven't tested it) once you make the container div's font size match that of the contents.

    If it's the second case, if any given instance can have more than one font size in its children, then my suggestion would be to use display:none; on all of the children you wish to hide (you can use the :nth-child(n+4) pseudo class in CSS to make short work of this). Then simply give the parent div a setting of overflow:auto; and, if needs be, a max-height setting so that you will eventually get a scrollbar on the container if you have enough child elements present.

    Overall, I'm picturing something like this:
    Code:
    <!doctype html>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
    <title>Example</title>
    <style type="text/css">
    *{padding:0;margin:0;}
    body{font-family:'verdana';}
    p{font-size:12px;}
    h1{font-size:24px;}
    h2{font-size:50px;}
    h3{font-size:20px;}
    h4{font-size:18px}
    h5{font-size:16px;}
    h6{font-size:14px;}
    #shell{width:400px;max-height:400px;overflow:auto;border:1px solid #000;margin:0px auto;}
    #shell>ul{list-style-type:none;}
    #shell>ul>li{padding:2px 5px;}
    #shell>ul>li:nth-child(even){background-color:#e4e4e4;}
    #shell>ul.collapsed>li:nth-child(n+4){display:none;}
    #control{display:block;width:400px;text-align:center;font-size:14px;margin:50px auto 0px;border:1px solid #000;cursor:pointer;border-bottom:0;}
    </style>
    <script type="text/javascript">
    var panel = function(){
    	var target;
    	var init = function(){
    		if(document.getElementById('list')){
    			target = document.getElementById('list');
    		}
    		else{
    			target=false;
    		}
    		if(document.getElementById('control')){
    			var control = document.getElementById('control');
    			if(control.addEventListener){
    				control.addEventListener('click',function(){toggle();},true);
    			}
    			else if(control.attachEvent){
    				control.attachEvent('onclick',function(){toggle();});
    			}
    			else{
    				control.onclick = function(){panel.toggle();};
    			}
    		}
    		else{
    			control=false;
    		}
    	};
    	var toggle = function(){
    		if(target){
    			if(target.className){
    				target.removeAttribute('class');
    			}
    			else{
    				target.setAttribute('class','collapsed');
    			}
    		}
    	};
    	return{
    		init: init,
    		toggle: toggle
    	};
    }();
    </script>
    </head>
    <body>
    <a id="control">Show/Hide</a>
    <div id="shell">
      <ul id="list" class="collapsed">
        <li><p>This is one entry.</p></li>
        <li><h1>This is another entry.</h1></li>
        <li><h2>This is one more entry.</h2></li>
        <li><p>This is one entry you won't see right away.</p></li>
        <li><h4>This is another entry that will not initially be visible.</h4></li>
        <li><h6>This is another entry that will not initially be visible.</h6></li>
        <li><h1>This is another entry that will not initially be visible.</h1></li>
        <li><p>This is another entry that will not initially be visible.</p></li>
        <li><h4>This is another entry that will not initially be visible.</h4></li>
        <li><h6>This is another entry that will not initially be visible.</h6></li>
        <li><h1>This is another entry that will not initially be visible.</h1></li>
        <li><p>This is another entry that will not initially be visible.</p></li>
        <li><h4>This is another entry that will not initially be visible.</h4></li>
        <li><h6>This is another entry that will not initially be visible.</h6></li>
        <li><h1>This is another entry that will not initially be visible.</h1></li>
        <li><p>This is another entry that will not initially be visible.</p></li>
        <li><h4>This is another entry that will not initially be visible.</h4></li>
      </ul>
    </div>
    <script type="text/javascript">panel.init();</script>
    </body>
    </html>
    It will be the perfect vertical height every time, no matter which font sizes are present around or within it.

    Honestly, this is how I would do it whether your usage is the first case or the second case of my initial estimates because it takes less (really no) maintenance on the container to make it work...
    Last edited by Rowsdower!; 10-17-2012 at 06:10 PM. Reason: clarification
    The object of opening the mind, as of opening the mouth, is to shut it again on something solid. –G.K. Chesterton
    See Mediocrity in its Infancy
    It's usually a good idea to start out with this at the VERY TOP of your CSS: * {border:0;margin:0;padding:0;}
    Seek and you shall find... basically:
    validate your markup | view your page cross-browser/cross-platform | free web tutorials | free hosting

  • #4
    Regular Coder
    Join Date
    May 2007
    Posts
    104
    Thanks
    19
    Thanked 12 Times in 12 Posts
    Thanks jamaks. I don't think I am using the em type of units properly, your description should help.

  • #5
    Senior Coder Rowsdower!'s Avatar
    Join Date
    Oct 2008
    Location
    Some say it's everything.
    Posts
    2,027
    Thanks
    5
    Thanked 397 Times in 390 Posts
    Quote Originally Posted by >ssp-cdr< View Post
    ...I figure that setting the height of the DIV using em units is the best approach because these units are relative to the size of the text being used, so if larger text is used in some lists then more space will be made to accommodate the larger text (rather than specifying the height in pixels which would require an adjustment of the numerical value in the code if the text size changes)...
    They're only relative to the size of the text being used at the DOM level at which they are applied. Unless your list contents are specifically set up to ALWAYS inherit exactly the font size of the container div you will end up with problems. Without seeing your HTML/CSS there is no way for me to know if this holds true for you, but I would generally doubt it. That's not how most people seem to code.

    So I still think the crux of your problem is inheritance, and you will have a hard time controlling that while keeping your code portable. In most cases (and we can only guess whether or not this is the case without seeing your actual HTML/CSS) your container will have some arbitrary font size applied to it through inheritance that is NOT necessarily attached to the font size of the elements it contains.

    Unless you specifically set the elements within the container to inherit their font size from the container (such as by using .my_container *{font-size:inherit !important;}) you are going to get inconsistent results. Even if you tackle that issue you will still have another problem to work around: If margins, padding, or borders exist on any of your elements from your list then em units used for the container will not be correct anymore. (Going even deeper than just the mere existence of margins/padding/borders...how, for example, would you adjust for a 1px border between results when you're using em units for the container's height?) So even this seemingly innocuous factor potentially throws your entire approach into disarray if you tweak the list style at some point.

    You wouldn't have any of these problems - or any of the math to work out - if you changed your approach from hiding overflow to something more flexible...such as using display:none;. Using display to control the length of the list means you don't need to do squat other than change from display:none; to display:block; and you're done, regardless of any font-size, line-height, padding, margins, or borders that may be applied to the contents of the div. It's perfectly portable, it's flexible, and it requires no real maintenance.

    Considering portability and ease of use issues I think you're taking the hard road just for the sake of using overflow:hidden; rather than display:none; to hide your extended list of results.

    Just saying...
    The object of opening the mind, as of opening the mouth, is to shut it again on something solid. –G.K. Chesterton
    See Mediocrity in its Infancy
    It's usually a good idea to start out with this at the VERY TOP of your CSS: * {border:0;margin:0;padding:0;}
    Seek and you shall find... basically:
    validate your markup | view your page cross-browser/cross-platform | free web tutorials | free hosting


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •