CSS | White spaces in 100% height elements - html

I'm writing here because I've got a problem with CSS. I have a .container div that contains another div set to position:absolute, top:0, left:0 and width:100%; height:100%. However I keep seeing these kind of white spaces, that when I zoom in the page disappear. Any solution?
.loop {
display: block;
position: absolute;
height: 36px;
background: white;
border: 2px solid black;
box-sizing: border-box;
width: 250px;
top: 7px;
left: 50%;
transform: translateX(-50%);
border-radius: 5px;
overflow: hidden;
transition: background 0.2s;
}
.goPrev,
.goNext {
position: absolute;
width: 36px;
height: 100%;
box-sizing: border-box;
top: 0;
display: flex;
justify-content: center;
}
.goMid {
position: absolute;
top: 0;
left: 36px;
width: calc(100% - 72px);
height: 100%;
font-family: "Poppins";
padding-top: 9px;
text-align: center;
box-sizing: border-box;
}
.goMid:hover,
.goPrev:hover,
.goNext:hover {
background: rgba(0, 0, 0, 0.3);
}
<body>
<div class="loop">
<div class="goPrev">
</div>
<div class="goMid">
Help me.
</div>
<div class="goNext">
</div>
</div>
</body>
That is just a draw.
Here you have the screenshot

Well, I'm not totally sure what to do, but the following changes seem to fix the problem for me. I changed:
Set .loop overflow from hidden to visible
Set .goMid top from 0 to -1px
The .goMid height from 100% to calc(100% + 2px)
When I moved the inner div underneath the border using top: -5px I still saw the whitespace until I changed the outer div overflow property to visible. Then if you stretch the inner div a little it seems to solve the problem. It helps that your outer div has a thick border.
.loop {
display: block;
position: absolute;
height: 36px;
background: white;
border: 2px solid black;
box-sizing: border-box;
width: 250px;
top: 7px;
left: 50%;
transform: translateX(-50%);
border-radius: 5px;
/* HERE */
overflow: visible;
transition: background 0.2s;
}
.goPrev,
.goNext {
position: absolute;
width: 36px;
height: 100%;
box-sizing: border-box;
top: 0;
display: flex;
justify-content: center;
}
.goMid {
position: absolute;
/* HERE */
top: -1px;
left: 36px;
width: calc(100% - 72px);
/* HERE */
height: calc(100% + 2px);
font-family: "Poppins";
padding-top: 9px;
text-align: center;
box-sizing: border-box;
}
.goMid:hover,
.goPrev:hover,
.goNext:hover {
background: rgba(0, 0, 0, 0.3);
}
<body>
<div class="loop">
<div class="goPrev">
</div>
<div class="goMid">
Help me.
</div>
<div class="goNext">
</div>
</div>
</body>
For what it's worth, I think #MarkP may have a good point. Combining absolute positioning and flexbox does feel like maybe a code smell. But, I don't know what the context is in your code and my flexbox-fu is a little shaky.

ACTUAL GENERATED VIEW:
I added text to all 3 nested divs and got the following centered display.
You can see all your text is bunched together. I am going to review your code and the offer a way forward. You may find you need to re-word your problem to allow us to help you better. My assumption is you are trying to set-up a tool to navigate through some type of media, such as images or pages.
CODE REVIEW
In review of your Code i can see you are trying to use a 3 part display using flexbox. Except you have also included absolute positions which prevents relative display of the divs alongside each other. Now i know you are concerned about white space but i am going to suggest a way to better use flex-box as well as debugging the whitespace, although it would be better to start again with a appropriate flexbox structure.
WHITE SPACE DEGUGGING
My suggestion first would be to remove CSS that could be causing this and then re-introduce the CSS progressively. If you are using Google Chrome you can use the insight tool to adjust the live CSS. Simply right-click on the area you wish to inspect and the CSS being used there will be displayed. You can edit directly in the CSS display and it will change the page behaviour, this is great for debugging and seeing what CSS improves your layout. Once you find the CSS you need you can replicate that in your code.
I would start with removing the following and see how you go:
Remove overflow:hidden;
When you look closer you can see the style code allows for 36px for each div on the left and the right. There may be an image missing from the .goPrev and .goNext divs, where your white space is now. Not sure if you copied your code from somewhere or wrote this from scratch?
TRY STARTING WITH A NEW FLEX-BOX STRUCTURE
I recommend creating your divs from scratch using one of the approaches found here: Common CSS Flexbox Layout Patterns with Example Code . Flexbox is super simple and a great way to build mobile responsive layouts.

Related

Button refusing to stay put in scrolling div

I have a number of buttons in a div that refused to stay in a fixed position when the div scrolls, and I cannot see why. I have done this elsewhere so I should be able to do it, but I'm going around in circles today.
I have isolated enough of the application to reproduce it easily. It places a div in the centre of the screen and puts a small quit button in the top-right. I want the button (and all my others) to remain fixed relative to the div. What am I missing?
<!DOCTYPE html>
<html>
<head>
<title>Scroll</title>
<meta charset='utf-8'/>
<style>
div.dt-baseContainer {
width: 50vw;
height: 50vh;
min-width: 400px;
min-height: 300px;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
position: absolute;
border-radius: 20px;
overflow: auto;
}
div.dt-container {
background-color: lightblue;
border: 3px solid royalblue;
text-align: center;
}
button.dt-quit {
border-style: solid;
border-radius: 4px;
border-color: inherit;
width: 20px;
height: 20px;
background-color: white;
color: red;
font-weight: bold;
font-size: 12px;
text-align: center;
margin: 0;
padding: 0;
z-index: 20;
top: 5px;
right: 5px;
position: absolute;
cursor: pointer;
}
</style>
</head>
<div class='dt-baseContainer dt-container' id='dt_container'>
sdfsdf1<br>sdfsdf2<br>sdfsdf3<br>sdfsdf4<br>sdfsdf5<br>sdfsdf6<br>sdfsdf7<br>sdfsdf8<br>sdfsdf9<br>sdfsdf10<br>
sdfsdf11<br>sdfsdf12<br>sdfsdf13<br>sdfsdf14<br>sdfsdf15<br>sdfsdf16<br>sdfsdf17<br>sdfsdf18<br>sdfsdf19<br>sdfsdf20<br>
sdfsdf20<br>sdfsdf21<br>sdfsdf22<br>sdfsdf23<br>sdfsdf24<br>sdfsdf25<br>sdfsdf26<br>sdfsdf27<br>sdfsdf28<br>sdfsdf30<br>
<button id='dt_quit' class='dt-quit' title='Stop'>X</button>
</div>
</html>
[Edited] Of course, position:fixed; is not relevant unless it's fixed relative to the screen so I removed the mention. But I c=still cannot get this simple thing to work.
I hate having to answer my own question, but this was me being silly ... of course.
The suggestion above that my transform was the problem is a red herring. It is basically not possible to fix an element relative to its container in a scrolling flow.
The solution was to put both my scrolling div and my buttons inside an extra containing non-scrolling div. Not only does this make sense -- the container encapsulates both scrolling and non-scrolling content without having to put the latter inside the former -- but my initial code was very nearly there.
Taking my existing dt-baseContainer class and putting it on an outer div fixes the problem.

Using CSS to make arrow-headed div

I am trying to implement a arrow-headed div. Below is the part of the code that is relevant to the post/question. I have been trying to figure out how to get this done for a while now but no success.
I have a grandparent div, a parent div with a child as follows
<div className="main-segment-container">
<div className="panel panel-default segment-select-box">
<div className="panel-header segment-select-box-header">MAIN SEGMENT</div>
<div className="panel-body segment-select-box-body">
<div className=has-subsegments'>
<input type="checkbox" className="form-check-input" value={checkedSegment.category_id} onChange={this.segmentChecked} />{' '}
<label className="form-check-label">{checkedSegment.name}</label>
</div>
</div>
</div>
</div>
Here is what I am trying to achieve (notice the arrowhead):
I am able to achieve this with this css:
.main-segment-container{
width: 100%
}
.has-subsegments{
background-color: #215C64;
width: 100%;
color: #fff;
position: absolute;
height: 30px;
}
.segment-select-box {
border-radius: 3px;
width: 100%;
/* max-height: 400px; */
/* overflow: scroll; */
position: relative;
}
.segment-select-box-body{
width: 100%;
max-height: 400px;
overflow: scroll;
padding: 0px;
display: inline-block;
}
.has-subsegments::after{
content: "";
margin-top: -15px;
border-top: 15px solid transparent;
border-bottom: 15px solid transparent;
position: absolute;
border-left: 21px solid #215C64;
width: 0;
height: 0px;
right: -20px;
top: 50%;
}
Problem:
When I use the css above, the .has-subsegments element seems to be at a fixed position when I scroll. Like this:
Question
How do I implement scroll without removing the element from the normal position?
Note:
When i remove scroll from .segment-select-box-body class, everything works perfect but the children list becomes very long, therefore a scroll is needed.
adding position: relative; to .segment-select-box-body class makes the :after pseudo-element invisible.
EDIT
See JSFIDDLE here : https://jsfiddle.net/uuwhndgu/16/
EDIT
Thanks for posting the jsfiddle. I don't think, what you're trying to achieve is possible the way you are trying to do it.
I updated the fiddle with a suggested workaround/fix: https://jsfiddle.net/uuwhndgu/34/
what I did, is giving the wrapping col a little more width (you probably would have to either increase the col to .col-md-3 or decrease the width of .segment-select-box a little. You probably need to do the latter anyway), a max-heightof 200px and a overflow-y: scroll;. I set the width of .segment-select-box to 90% and changed position: absolute;of .has-subsegments to position: relative;. I don't know if this helps you but I BELIEVE, that there aren't many ways to achieve what you are trying to achieve.
Original answer
I am not quite sure how you intend this thing to behave. But if the highlighted entry (the one with the arrow) just ought to stay where it was, I think you can simply replace position: absolute; with position: relative; in your .has-subsegments class. Now, I wasn't able to recreate this anything close to perfectly, because it's a react app, but still, you should get the idea:
with position: absolute; on .has-subsegments
with position: relative; on .has-subsegments

Element overlapping when absolute positioning applied on a Custom Tag - HTML, CSS

I created a custom tag called <bubble></bubble> and its styles can be applied using the custom type attribute.
Code:
bubble[type=normal] {
border-radius: 10px;
background-color: #5e9bff;
text-align: center;
color: white;
padding: 6px;
width: 50px;
}
<bubble type="normal">Hello!</bubble>
The problem comes in positioning the element when placed with the div tags. First of all, the width: 50px; gets ignored unless I use Position: Absolute; which has another problem I'll describe below. Second, It partially overlays the text when <div></div> tags are used even after applying the margins on Top and Bottom.
Code with Absolute Positioning:
bubble[type=absoluteposition] {
position: absolute;
border-radius: 10px;
background-color: #5e9bff;
text-align: center;
color: white;
padding: 6px;
width: 50px;
margin-top: 10px;
margin-bottom: 10px;
}
<bubble type="absoluteposition">Hello!</bubble>
The problem here is position: absolute; acts like float: left; which I don't want to use even after using margins on top and bottom. This problem also occurs with div tags.
Demo in JSFiddle.net
If you have a solution OR You think there is a problem in my code OR You think there is an Alternative way to fix this problem OR You need more details on my Question, please Reply.
if you want to specify , height , width on above when using absolute than you may try wrap bubble tag in another div with relative position like :
<div class="some" style="
position: relative;
display: inline-block;
width: 100px;
height: 50px;
">
<bubble type="absoluteposition">Hello!</bubble>
</div>
Cheers !

(HTML + CSS) Knowing exact distances in em

I'm kind of knew (some days) to this so this might be a dumb question.
I'm trying to make a navbar with three links/buttons. Two of them, when hovered, simply change the background to a darker one, the third one, opens a small menu with more links/buttons.
This is what I did (probably not the best method, but the first that came into my mind):
http://jsbin.com/woxodovoxo/1/edit?html,css
My problem is that on the button in the middle, the positions are not right (you can see that the button flickers a little when you hover your mouse over it, although this doesn't happen on the other buttons).
This is happening because I wasn't able to put #text-dropdown and #dropdown-div on the same starting position, since I couldn't find the right value for the "margin-top; padding-top" on #dropdown-div
From what I see on the code, .headertext is 0.5em (+ font-size) underneath the top of the page.
The problem comes with #dropdown-div, since I don't know its original position (without any tweaking) relative to the top of the page. If I were to know that, I could simply make a calculation to know which values to put in "margin-top; padding-top" on #dropdown-div.
Could you help me with that?
Also, percentages and em's don't seem to go well together, specially on the navbar when zooming in/out. What alternative could I use? Everything with em's? Everything with percentages? Or something else?
Thanks
Would this solve your problem? I didn't copy over your exact code because it was exhausting to read, but hopefully it gets you in the write direction. If you set an objects position to be absolute with its parent set to relative you can move it around relative to its parent.
Also, the box-sizing attribute may help you in the future. Makes it so that the padding/borders are included in the size calculations.
div#navbar {
width: 100%;
height: 2em;
}
div#navbar *,
div#navbar {
padding: 0;
margin: 0;
background-color: #3ff;
}
div#navbar div {
display: inline-block;
position: relative;
box-sizing: border-box;
height: 100%;
width: 150px;
}
div#navbar div>div {
display: none;
position: absolute;
top: 100%;
left: 0;
height: auto;
}
div#navbar div:hover>div {
display: block;
}
<div id="navbar">
<div>Something 1</div>
<div>Submenu
<div>
Other text
<br />Yup
</div>
</div>
<div>
hello
</div>
</div>
.headerlink{
height: 3em;
line-height: 3em;
width: 25%;
z-index: 1;
position: fixed;
}
.headertext{
text-align: center;
font-size: 1.3em;
font-family: 'Verdana';
color: #E3E3E3;
font-weight: bold;
}
#dropdown-div{
position: absolute;
top:100%;
width:100%;
background-color: #57a58a;
opacity: 0;
}
Modify the above styles and delete the below one
#hd2:hover #text-dropdown{
opacity: 0;
}
Edit:
Add this too..
#hd2:hover{
background-color: #57a58a;
}
and remove this extra option:
<div class="header-dropdown">Page2</div>

making two divs line up side by side without gap

I have seen people ask questions about how to get two divs to line up side by side. I can get mine to do that just fine.
My problem is that they will not smash up against each other. There always seems to be a gap.
For example, I have a wrapper div with a width of 500px. Inside that div I have two other divs with widths of 250px.
They will not line up next to each other because there is not enough space for each other.
When I set the width to 248px they do line up but with a 4px gap between each other.
I have an example of this code located here:
https://c9.io/riotgear66/day1/workspace/sams/html/index.html
Please feel free to take a look at it and try adjusting it with your browser's element inspector.
The layout problem is the result of applying display: inline-block to the div elements.
Any white space between those div elements are taken into account when laying out the content.
You could remove the white space (linefeed or carriage return) between the div's if you don't mind how your source code looks.
Since your parent container has specific dimensions (500px x 300px), I would use absolute positioning to place the child elements. This would make it easier to position your logo motif over the other images.
You could also use floats as stated in other responses, not any easier or harder.
In this application, the layout is fixed so there are no design considerations for a responsive or flexible design, so either approach is valid.
Demo
You can see how this might work in the following demo: http://jsfiddle.net/audetwebdesign/hZ5dB/
The HTML:
<div class="container">
<div class="panel ul"></div>
<div class="panel ur"></div>
<div class="panel ll"></div>
<div class="panel lr"></div>
<div class="overlay"><span>Cats</span></div>
</div>
and the CSS:
.container {
border: 1px dotted blue;
width: 500px;
height: 300px;
position: relative;
margin: 0 auto;
}
.panel {
width: 250px;
height: 150px;
position: absolute;
}
.ul {
background: red url("http://placekitten.com/400/400") -50px -20px no-repeat;
top: 0; left: 0;
}
.ur {
background: red url("http://placekitten.com/300/300") 0px -30px no-repeat;
top: 0; right: 0;
}
.ll {
background: red url("http://placekitten.com/350/250") -20px -20px no-repeat;
bottom: 0; left: 0;
}
.lr {
background: red url("http://placekitten.com/300/200") 0px -30px no-repeat;
bottom: 0; right: 0;
}
.overlay {
position: absolute;
top: 50%;
left: 50%;
margin: -50px 0 0 -50px;
width: 100px;
height: 100px;
background-color: red;
border-radius: 50%;
}
.overlay span {
display: block;
background-color: gray;
border-radius: 50%;
text-align: center;
vertical-align: middle;
width: 80%;
height: 80%;
margin: 10%;
line-height: 80px;
}
I also show how you can create the circular motif without having to modify the original background images, saves a bit of work with PhotoShop or similar.
You shouldn't be using
display: inline-block;
Make them:
float: left;
Here is a jsfiddle sample of how it should be.
http://jsfiddle.net/Tqdqa/
The problem lies in the white space in your HTML. When using display: inline-block, white space after elements is taken into account like Marc Audet said.
To fix it without changing your current method, you must remove that white space. The easiest way I've found to do so while still maintaining readability of the HTML is by commenting it out, or using <!-- after each element and --> before the next element. This prevents having to change the whole structure and you can make each one 250px again as well
You could also move the closing > to the next line, move everything after the opening <div> to the next line, or use margin-left:-4px; for each element after the first. Or use a method described by others here, floating it or using FlexBox
Here is the CSS Tricks page that references this situation and provides more detail