0

I try to design some kind of html , but I want to use images instead of text . So I've build some very basic html outline, with two divs for every option and two divs around them:

<div class="dungeon-action-select-container">
    <div class="dungeon-action-select">
        <div class="border"><div></div></div>
        <div class="border"><div></div></div>
        <div class="border selected"><div></div></div>
        <div class="border"><div></div></div>
        <div class="border"><div></div></div>
    </div>
</div>  

The point of the most inner divs is to contain images later. The .border divs are there to allow different visual effects for selected options. The .dungeon-action-select should contain a vertical scrollbar, when there are more options to select from.

The container div is there, to allow the whole "thing" to be placed fixed to the top left of the screen.

My Problem: When the .dungeon-action-select div is to small, to display all options, there will be a vertical scrollbar. But the vertical scrollbar is displayed within the div, not attached at the right. One solution, I came up with, is to make the .dungeon-action-select 15px greater, than the inner divs. But that is just a hack because the scrollbar could (of cause) be bigger than 15px.

Here is my "solution" so far:

.dungeon-action-select-container {
    position: fixed;
    width: 125px; /* 80px + 2 * 15px + width of scrollbar */
    top: 60px;
    left: 25px;
}

.dungeon-action-select-container .dungeon-action-select {
    height: 320px;
    overflow: auto;
    position: relative;
}

.dungeon-action-select-container .dungeon-action-select .border {
    background-color: #333;
    padding: 7px 15px;
}

.dungeon-action-select-container .dungeon-action-select .border div {
    width: 80px;
    height: 80px;
    background-color: black;
}

So I'm looking for a way to automatically make the scrollbar containing div big enough to have place for the option divs and the scrollbar (when needed). Or a way to attach the scrollbar from outside of the .dungeon-action-select div. Or as a last resort, some trick to determine, portable the size of the scrollbar.

Any pointers are welcome; here is a fiddle to fiddle with: http://jsfiddle.net/b8kUr/2/

Solution: I wish Sharkys idea would have worked, but the only working solution, I've found, is to use JavaScript (as Marcelo suggested) to calculate the width of the scrollbar and to resize the containing div accordingly (the solution is based on an other question, I've found here on SO):

scrollBarHeightAndWidth = null

calcScrollBarHeightAndWidth = ->
    scrollDiv = document.createElement("div")
    scrollDiv.className = 'tools-scrollbar-measure'
    document.body.appendChild(scrollDiv)

    # Get the scrollbar width
    result = {
        width: scrollDiv.offsetWidth - scrollDiv.clientWidth,
        height: scrollDiv.offsetHeight - scrollDiv.clientHeight
    }

    # Delete the DIV 
    document.body.removeChild(scrollDiv)

    result

Tools.scrollBarWidth = ->
    scrollBarHeightAndWidth = scrollBarHeightAndWidth || calcScrollBarHeightAndWidth()
    scrollBarHeightAndWidth.width

and some little css to hide the test div and configure it to have a scrollbar:

.tools-scrollbar-measure {
    width: 100px;
    height: 100px;
    overflow: scroll;
    position: absolute;
    top: -9999px;
}
Torsten Robitzki
  • 3,041
  • 1
  • 21
  • 35

2 Answers2

1

im not quite sure if i understand this correctly... why not use an outer div for the bar?

http://jsfiddle.net/b8kUr/4/

<div class="dungeon-action-select-container">
    <div class="scrollbar_wrap"> <!-- overflow:auto;height:200px; -->
        <div class="dungeon-action-select"> <!-- changed overflow to none -->
            <div class="border"><div></div></div>
            <div class="border"><div></div></div>
            <div class="border selected"><div></div></div>
            <div class="border"><div></div></div>
            <div class="border"><div></div></div>
        </div>
    </div>
</div>     

update:

i still dont completely understand.... if you want your dungeon-action-select-container to has a fixed width, lets say 125px so it includes the bar but you are afraid that some bars in different browsers maybe need more try this:

http://jsfiddle.net/b8kUr/11/

you ll just lose some pixels.(i made the dungeon-action-select-container 120px to show you the effect)

Sharky
  • 6,154
  • 3
  • 39
  • 72
  • Now, the problem is, that the width of the .dungeon-action-select-container div still have to be 15px bigger than the content. Do you have any solution for this? – Torsten Robitzki May 31 '13 at 16:02
  • 1
    @TorstenRobitzki check the update, let me know if i understand correctly :) – Sharky May 31 '13 at 16:37
  • The problem stays the same: magic number 125px == x + width-of-scrollbar. I've tried to set the width of .scrollbar_wrap to 100% or omit the width attribute at all, but in both cases, the scrollbar_wrap uses the whole page then. I think your idea looks very promising. I will try to add a div to the right of the "option" divs (tomorrow). – Torsten Robitzki May 31 '13 at 20:19
1

Scrollbars are always displayed inside the block element. You could use JQuery to determine if a scrollbar is needed, if true then make your div wider.

var height = 0;

$('div.border').each(function(){
    height += parseInt( $(this).height() ); 
});

if( height > parseInt( $('div.dungeon-action-select').height() ) ) {
    $('div.dungeon-action-select-container').css('width','+=18px');
} 

See it in action: http://jsfiddle.net/b8kUr/8/

Marcelo Pascual
  • 810
  • 8
  • 20
  • @Macelo Pascual But that still means, that I have to know the width of the native scrollbar on the current browser. Not impossible, but I'm hopping for something easier. – Torsten Robitzki May 31 '13 at 16:04
  • 1
    @TorstenRobitzki there are (weird) ways to know scrollbar size: http://stackoverflow.com/questions/986937/how-can-i-get-the-browsers-scrollbar-sizes. Also, set the width of `div.dungeon-action-select-container` 30px wider, and the css width of the JS on `18px`. I updated the post. – Marcelo Pascual May 31 '13 at 16:13