3

Edit 1 (reduced the problem to a jsfiddle):

I removed some unnecessary detail of the original problem.

I am trying to center a popup in the window. Because of how it will be used in the original context, the popup's width will be dynamic. Its only contents will be text, but it won't be known how long that text will be. In most cases it will fit on one line, but if the text is longer and the user has a lower screen resolution, it may need to occupy 2 lines, and I would like to keep all the text on the screen. The text is static in the jsfiddle, so that is obviously not what is causing the issue. I'm just clarifying in case anyone is wondering why I haven't tried setting a width for the popup. I'm using jquery to get the width using outerWidth() and $(window).resize() to trigger the centering function when the browser window is resized.

It works fine as long as the popup's width is smaller than the element containing it. I would like for the popup to just take the full width of its container if it is made small enough that the text has to go to two lines. As you will see in the video below, if you make a large adjustment in the browser window size, the width isn't always being reported correctly, which is causing the element to have a space on the left side instead of being centered. In other words, outerWidth() is reporting a width different than what is being rendered by the browser.

See this video for a demonstration of the problem: http://youtu.be/Tnq6nrrDKvw

This is happening for me in Firefox, Chrome, IE, Opera, and Safari. Perhaps it is a problem with jquery's outerWidth function. Or perhaps I don't understand something about how it is supposed to work. Is there another method to accomplish what I'm trying to do?

Here is the javascript, nothing too complicated:

function center_horizontally(id)
{
    var windowWidth = document.documentElement.clientWidth;
    var popupWidth = $(id).outerWidth();

    var new_left = Math.max(0, windowWidth/2 - popupWidth / 2);

    ...

    $(id).css('left', new_left + 'px');
}

$(function(){
    $(window).resize(function() {
        center_horizontally('#popup');
    });

    center_horizontally('#popup');
});

The only important css is that the popup has position: fixed and no set width or height. If I set the width of the popup, it sticks along the left side like it should, but the text extends beyond the right boundary. I would like to keep all the text on the screen and have it take the full width and jump some text down to the next line if needed. When the width gets low enough for that to happen, I just want the notice to occupy the entire width of the viewing area.

http://jsfiddle.net/dnag/qHjVG/5/

Edit 2 (the solution):

This is the solution I ended up using thanks to the help I got.

http://jsfiddle.net/dnag/qHjVG/44/

Instead of repositioning the popups, the popups are left with an auto width and display: inline-block. They are contained inside a div with fixed positioning. When the window is resized, the containing div is resized and repositioned. You can specify how much horiziontal space you want outside of the popups when the windows is reduced by changing the number in the function. There might be a way to do this with css only, but I'm just happy to have something functional at the moment.

dnag
  • 335
  • 1
  • 9
  • +1 for a video description of the problem :] – David Hellsing Aug 06 '13 at 21:39
  • Could you post the styling of the text bubble? – EZLearner Aug 06 '13 at 21:44
  • I don't know whether it's the cause but maybe try: `var timer; $(window).resize(function() { clearTimeout(timer); timer = setTimeout(function(){ center_horizontally('#subtitle_notice'); }, 100); /* your other resize code */ });` this will only trigger once resizing has stopped. I'm not sure whether it will help but it's worth a try. – Joe Aug 06 '13 at 21:47
  • We’ll need more info about `#subtitle_notice`. Is it positioned absolute or relative? Does it have margins? Please post some more code (CSS) or a fiddle. – David Hellsing Aug 06 '13 at 21:49
  • Thank you for the quick replies. I edited my post with the CSS details. I will have to try the timer later tonight as I have to leave for several hours. If that doesn't work I will make a boiled-down jsfiddle. – dnag Aug 06 '13 at 22:33
  • Are you sure the parent div of #subtitle_notice doesnt have any other element that happens to have a fixed width or somehow takes up a minimum width. Seems like the #subtitle_notice takes up the width of its parent that doesnt resize beyond a certain width eventhough you resize the window. For example, a large image. – Jithesh Aug 06 '13 at 22:45
  • Oh dang, I think you may be right about it being contained in a parent div that is affecting the positioning. The way it stays off the left edge is similar to how the content section of the page moves because it has a fixed minimum width and is auto-centered. I think my html structure is not what I think it is. I'll take a look tonight. Thank you all so much for replying, I'll update when I know more. I appreciate you all taking time to help lost souls like myself. I feel like I barely have enough time to maintain my own sanity most of the time. – dnag Aug 06 '13 at 23:04
  • Thanks for the suggestions, but neither worked. I created a jsFiddle that demonstrates the issue (see Edit 2). – dnag Aug 07 '13 at 01:25
  • The fiddle works just fine in my chrome and firefox. which browser/version are you trying it in? – Jithesh Aug 07 '13 at 05:10
  • Thanks for the reply Jithesh. Please see the video I posted in my edit above to make sure you aren't having the same issue. It's tough to describe so I made a new video using the jsfiddle as a demo. I tested all 5 major browsers and had the same issue in all of them, so it seems unlikely it would be something to do with my browser. – dnag Aug 07 '13 at 21:57

1 Answers1

1

So I might be misunderstanding but you don't need JS at all for this effect. This seems like a case of beating the sh!t out of something with a JS-hammer instead of using some CSS-fu. I've included two examples in my HTML below one with just a single line of text, one with more than that (3 lines when I plugged it into the fiddle)

I don't have a damn fiddle account so here is the pertinent pieces from your fiddle:

1) no JS needed. (especially not things like outerwidth et al which can cause unnecessary reflows/repaints.

2) HTML

<div id="popup">
    This is some sample text, just a little bit of sample text.
</div>
<div id="popup" style="top:120px;">
    This is some sample text, just a little bit of sample text.
    This is some sample This is some sample text, just a little bit of sample text.
    This is some sample This is some sample text, just a little bit of sample text.
    This is some sample 
</div>

3) CSS

#popup {
  background: #FFF;
  position: fixed;
  top: 50px;
  left: 0;
  border: 1px solid #000;
  box-shadow: 0 0 3px #CCC;
  padding: 10px; 
  width:auto;
  max-width:100%;
}

--EDIT-- ALT version centered like the top of the question implies:

HTML

<div id="popupWrapper">
    <div id="popup">
        This is some sample text, just a little bit of sample text. little bit 
    </div>
    <div id="popup">
        This is some sample text, just a little bit of sample text. little bit of s little bit of s little bit of s
    </div>
    <div id="popup" style="top:120px;">
        This is some sample text, just a little bit of sample text.
         This is some sample This is some sample text, just a little bit of sample text.
         This is some sample This is some sample text, just a little bit of sample text.
         This is some sample 
    </div>
</div>

CSS

#popupWrapper {
    width: 100%;
    text-align:center;
    position:absolute;
}

#popup {
    background: #FFF;
    top: 50px;
    border: 1px solid #000;
    box-shadow: 0 0 3px #CCC;
    padding: 10px;
    max-width:100%;
    display: inline-block;
}
Nick Sharp
  • 1,881
  • 12
  • 16
  • That was assuming that this line from you post: "it sticks along the left side like it should" infers that you want it to stick to the left side of the screen normally... I just re-read your message and will try an attempt at centering horizontally to see if that was what you meant. – Nick Sharp Aug 08 '13 at 22:19
  • Yea sorry for the confusion. Unless I'm missing something obvious, it's not possible to position it in the center with space on either side when the width is set to auto. The only way I know how to center like that is with an auto margin and that requires a set width. I could maybe determine when the width of the space is too small and change the css to width: 100%. But I would have to do some more crazy js to accomplish that if it's even possible. – dnag Aug 08 '13 at 22:39
  • Doh. I use inline-block all the time (probably too much) and it never occurred to me to use it here. Thanks for the help! The width of 100% makes the right side go off the screen a little bit with the border and whatnot, but I can fix that. – dnag Aug 09 '13 at 16:06
  • No probs, you can get around the border and width issue if you set that element to box-sizing:border-box; Good luck. – Nick Sharp Aug 13 '13 at 15:46
  • I didn't know that property even existed, good to know. In my case, I ended up deciding it looked better with space around the box. I ended up just using javascript again. It works exactly as I want it to, and I included a new jsfiddle above. Perhaps it is possible to do it with css only, but I gave up after a few failed attempts. – dnag Aug 13 '13 at 19:55