2

The question is pretty straight-forward and I have read lots and lots of posts about the same issue, though in my specific case all these solutions are not working because I am probably handling it wrong or making it over-complicated.

Some of the solutions I tried:

Most of these posts come to the conclusion that you should use inline-block in combination with white-space: nowrap. Though after numerous trial and error tries, I actually kinda forgot what I did and did not try..

My specific case

I have a React application in which I want to display an hours-bar. This bar has a (sort-of) table layout but just with 1 row. The bar consists out of 15 cells (div's).

The problem

Each cell should have a specific text above it when a certain condition is met. So for example, I want to show a text value on the starting cell div, and the ending cell div and then each 5th cell again. It should look something like this:

enter image description here

I figured I could achieve this by making a 'Time' row inside the body of the time bar, however when I add it as a separate row, then the times / text will never be above the correct cells when the bar has multiple lines on the screen, you would then get something like this:

enter image description here

So my next idea was to make 2 separate div's inside the row where 1 div (the top div) functions as the header and the second div functions as the actual bar:

<TimeColumnBody>        
    <TimeColumnHeader>
        {(() => {
            if (item.showtime === true)
            {
                return <Test>{item.name}</Test>
            }
        })()}
    </TimeColumnHeader>
    <TimeColumn
        key={item.key} 
        name={item.name}
    >
    </TimeColumn>
</TimeColumnBody>

The above html get's rendered on each separate cell (time-step), so with the above example that would be 15 times (8:00 to 11:30 with steps of 15 minutes).

The objects TimeColumnBody, TimeColumnHeader and TimeColumn are created inside the react file and they are simple custom div elements with styling (using styled-components) :

const TimeColumnBody = styled.div`
    float: left;
    width: 100%;
    height: 100%;
    @media only screen and (min-width: 768px) {
        width: ${props => (props.span ? props.span / 44 * 100 : "2.27")}%;
        height: 100%;
    }
`;

const TimeColumnHeader = styled.div`
    display: flex;
    align-items: flex-end;
    height: 50%;
    background-color: blue;
    color: white;
    white-space: nowrap;
`;

const TimeColumn = styled.div`
    height: 50%;
    background-color: red;
`;

The creating of the entire table / time-bar happens in the React render part:

render() {
        return (
                <TimeContainer>
                    <TimeRow>
                        {this.renderTimeTable()}
                    </TimeRow>
                </TimeContainer>
        );      
    }

The renderTimeTable function is the part where the cells are being created (TimeColumnBody, TimeColumnHeader, TimeColumn elements).

The text inside the TimeColumnHeader div remains wrapped inside the div even with the white-space: nowrap; property:

enter image description here

I tried adding the white-space: nowrap; property to the TimeColumn div with no effect, then I added the display: inline-block property with no effect, then I tried adding it to some parent div's but also without result.

The entire styling looks (currently) as follows (style added inline for easier reading):

<div class="App" style="text-align: center; height: 100%; overflow: auto;">
    <div class="Nav-LeftPane" style="width: 15%; height: 100%; position: fixed; box-sizing: border-box; overflow-y: auto; float: left;">...</div>
    <div class="content" style="width: 85%; height: 100%; text-align: center; overflow: hidden; float: right;">
        <div class="content-timebar" style="padding-left: 1%; padding-right: 1%; padding-top: 3%; height: 100%;">
            <!-- The actual Time Bar : --> 
            <div class="TimeContainer" style="width: 100%; height: 10%;">
                <div class="TimeRow" style="height: 100%;"> <!-- This div also has some :after logic: .TimeRow::after { content: ""; clear: both; display: table; } -->
                    <!-- the cell part which gets generated 15 times -->
                    <div class="TimeColumnBody" style="width: 2.222%; height: 100%; float: left;">
                        <div class="TimeColumnHeader" style="display: flex; align-items: flex-end; height: 50%; background-color: blue; color: white; white-space: nowrap;">
                            08:00
                        </div>
                        <div class="TimeColumn" style="height: 50%; background-color: red;"></div>
                    </div>
                </div>
            </div>

        </div>
    </div>
</div>

I am now out of ideas and hope someone has a (better) solution to acheive this.

UPDATE

Added a CodePen: https://codepen.io/anon/pen/rqJgRx

5
  • Do you have the html code to reproduce that last screenshot? Commented Oct 17, 2018 at 14:30
  • Not related to your question, but you can optimize the content inside the TimeColumnHeader tag by just doing {item.showtime && <Test>{item.name}</Test>} and removing the code that's in there. You're essentially creating, calling and destroying a function every time that particular part renders. Commented Oct 17, 2018 at 14:32
  • Thanks Sergio Moura, tips like that are always welcome since I am still very new to React! The HTML is posted in the bottom of the main post. Commented Oct 17, 2018 at 14:57
  • Place everything into a public CodePen so we can play around :) Commented Oct 17, 2018 at 15:41
  • 1
    As requested, the CodePen: codepen.io/anon/pen/rqJgRx also added the CodePen in the main post. Commented Oct 17, 2018 at 19:25

1 Answer 1

1

The problem initially appears to be related to overflow or wrapping, but it is actually a z-index issue - because you are floating .TimeColumnBody left, each subsequent element has a higher z-index than the last and thus overlaps the previous item. I was able to fix this simply by adding a span to the first time with:

.TimeColumnHeader span {
   position: absolute;
}

See pen: https://codepen.io/anon/pen/NOyZOx

Sign up to request clarification or add additional context in comments.

1 Comment

Cheers! That fixed it :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.