Strange CSS margin problem - html

I'm styling a form designed by a client with the following structure:
<div class="formRow">
<div class="fieldName">
Email
</div>
<div class="fieldInput">
<input .../>
</div>
</div>
The width of the form is 500px, but the fieldName div and the fieldInput div stack on top of each other instead of sitting side-by-side. This is because (at least in Chrome and Firefox), the fieldName div is getting a computed right-margin of 340px, taking up the entire width of the form.
I can't seem to override this behavior, either. Entering a margin-right of 10px does nothing. And setting the width of the div either to a hard number or a percentage only changes the inside width, not the strange right-margin.
What CSS headache am I running up against, here?
BTW, here's the CSS:
.formRow{
padding: 3px 0 3px 0;
position: relative;
height: auto;
width: 100%;
}
.fieldName{
font-size: 12px;
margin-left: 10px;
margin-right: 10px;
width: 100px;
}
.fieldInput{
width: 200px;
}

One thing to take note of in your example code is that you are over-using DIVs. The same code could be written like this:
<div class="formRow">
<label class="fieldName">Email</label>
<input class="fieldInput" .../>
</div>
Or, even better:
<style type="text/css">
UL, UL LI
{
margin: 0px;
padding: 0px;
}
UL LI
{
list-style: none;
}
.fieldName{
font-size: 12px;
margin-left: 10px;
margin-right: 10px;
width: 100px;
}
.fieldInput{
width: 200px;
}
</style>
<ul>
<li><label class="fieldName">Email</label>
<input class="fieldInput" .../></li>
...
</ul>
By using DIV tags for both sections you are violating the semantic meaning of the tag, which is "this section of the page is distinct from this other section." What you really are trying to do is just style your Form label differently from your Input and we already have tags to describe those.

try adding
.fieldName {display: inline}
or
.fieldInput {display: inline}
or both

If you add a display: inline; to each element, that will allow them to sit side-by-side. Because they're rendered as block elements by default, the browser puts them on their own lines.
.fieldName{
font-size: 12px;
margin-left: 10px;
margin-right: 10px;
width: 100px;
display: inline;
}
.fieldInput{
width: 200px;
display: inline;
}

Related

How to fix 'overflow: auto' not working as intended?

I have made an unsorted list that contains tabs that get created dynamically based on the value of my amount input field. The div of this list has its overflow set to auto to create a scrollbar when too many tabs are created. But for some reason the overflow auto doesn't work as intended.
These pictures show that I can fit a maximum of 21 tabs without a scrollbar. However, as I increase the amount of tabs they get squished together until the 24th tab and only after the 25th has been added the scrollbar appears. (The borders are for visualization purposes and show the dimensions of the div that contains the list as well as the div that contains that div)
These are the respective sections of my HTML and CSS:
#amount-and-tabs-container {
display: flex;
}
.container {
width: 50%;
display: inline-block;
}
#amount-container {
width: 10%;
min-width: 75px;
}
#tabs-container {
width: 100%;
overflow: auto;
border: 1px solid blue;
}
#tabs {
display: flex;
list-style-type: none;
margin: 0;
padding: 0;
border: 1px solid red;
}
.tab {
cursor: pointer;
text-align: center;
font-weight: bold;
padding: 10px;
margin-left: 20px;
width: 24px;
min-width 24px;
background-image: url("tab.png");
background-size: 100% 100%;
}
.tab.active {
background-image: url("tab_active.png");
}
.tab:hover {
background-image: url("tab_hover.png");
}
<div id="amount-and-tabs-container">
<div class="container" id="amount-container">
<label id="amount-label" for="amount">Amount:</label>
<input type="number" id="amount" value="1" min="1">
</div>
<div class="container" id="tabs-container">
<ul class="tabs" id="tabs"></ul>
</div>
</div>
I have tried to add a width and min-width to the tabs, but it doesn't do anything in regards to this problem. I suspect the cause to be the margin on the tabs, but I am not sure. My leading theory is that the margin gets prioritized above the width.
Answer:
'flex-shrink: 0' fixed this.

Margin auto not being respected despite using display block

I have a div containing two label elements. Each label should be on a side of the div. As labels are inline elements, I have tried with display: block and also with display: inline-block for margins to take effect, but the result is not the expected one.
div {
color: #ffffff;
background-color: #3f3f3f;
}
label:nth-of-type(1) {
margin-left: 5px;
}
label:nth-of-type(2) {
display: block;
<!-- display: inline-block; -->
margin-right: 5px;
margin-left: auto;
}
<div>
<label>Left side label</label>
<label>right side label</label>
</div>
As you can see with the code execution, the second label is not respecting the margins and is being displayed underneath the first one.
The label must have a width and display:block to work with margin auto.
Today it's more flexibel to use flexbox for this.
div {
color: #ffffff;
background-color: #3f3f3f;
display:flex;
flex-flow: row nowrap;
justify-content: space-between;
}
label:nth-of-type(1) {
margin-left: 5px;
}
label:nth-of-type(2) {
margin-right: 5px;
}
<html>
<body>
<div>
<label>Left side label</label>
<label>right side label</label>
</div>
</body>
</html>
With more modern methods like CSS Grid or Flexbox, this can be accomplished. But my solution will be with raw CSS to keep at a similar level to OP's code.
Both labels will need to have display: inline-block applied to get both elements to be treated like block elements and remain on the same line. You'll also need to set a width to give them a container to work with when adjusting the text placement. For this example, we'll do width: 50%.
Note: inline-block elements that take up a full width: 100% will result in the labels being on separate lines unless you modify the html to remove the whitespace in between the elements. Read more why on this behavior here and a personal CodeSandbox of fixing this.
You'll notice I also removed margin-left and margin-right from the width calculation and instead used padding to result in the same spacing on the left and right.
HTML:
<body>
<div>
<!-- Remove whitespace between labels to not exceed width: 100% -->
<label>Left side label</label><label>right side label</label>
</div>
</body>
CSS:
div {
color: #ffffff;
background-color: #3f3f3f;
padding: 0 5px;
}
label {
display: inline-block;
width: 50%;
}
label:nth-of-type(1) {
text-align: left; /* Not necessary, but you can explicitly set the behavior you want. */
}
label:nth-of-type(2) {
text-align: right;
}
Codepen
you don't need to specify the display property, just let it be inline and play around with the float property to float them.
<style>
div {
color: #ffffff;
background-color: #3f3f3f;
display: block;
height: 20px;
width: 100%;
}
label:nth-of-type(1) {
margin-left: 5px;
float: left;
}
label:nth-of-type(2) {
float: right;
margin-right: 5px;
}
</style>
<html>
<body>
<div>
<label>Left side label</label>
<label>right side label</label>
</div>
</body>
</html>

Why does the form element take up 100% of the width?

I have a form element which I want to take up the same width as its children, with no margin, but no matter what I do the browser makes its width + margin take up 100% of the width.
Here is the html:
<div class="container">
<form method="GET" action="http://localhost/search" accept-charset="UTF-8">
<div class="search centered">
<div class="input-container">
<input type="text" name="query" class="searchbar" placeholder="What do you want to search?" />
<button type="submit" class="search-button">Search</button>
</div>
</div>
</form>
</div>
and the css:
#import url('//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-theme.min.css');
body {
margin: 10px;
}
.search * {
height: 35px;
}
.searchbar {
width: 450px;
}
.brandname {
position: relative;
font-size: 500%;
font-family: 'Lato', sans-serif;
color: #1f0e3e;
text-align: center;
margin-bottom: 30px;
margin-top: 5%;
}
body {
margin: 10px;
}
.input-container{
float: left;
display: block;
outline-style: solid;
outline-color: #e3e3e3;
outline-width: 1px;
}
.searchbar{
margin-left: 5px;
}
.search button {
background-color: rgba(152,111,165,0.38);
background-repeat:no-repeat;
border: none;
cursor:pointer;
/*overflow: hidden;*/
outline-width: 1px;
outline-style: solid;
outline-color: #e3e3e3;
color: white;
}
.search input{
outline-width: 0px;
}
form{
height: 30px;
width: 100px;
margin-left: 0px;
}
and here is a fiddle where you can see that even if you force the form to have a small width, the browser forces a left-margin to take up the rest of the space.
How can i get rid of this margin and make the form automatically take up the space of its child?
Adding display table to the form element will make it auto size to it's children elements.
form {
display:table;
}
Here is a working fiddle: https://jsfiddle.net/bnah6jLe/
Why the form is 100% width by default
By default forms in most browsers have their display type set to block. In the specification for block context it is defined as follows.
In a block formatting context, each box's left outer edge touches the
left edge of the containing block (for right-to-left formatting, right
edges touch)
Reference: https://www.w3.org/TR/CSS21/visuren.html#block-formatting
In short display:block is 100% width unless specified otherwise.
Side Note
Question: Why was table used for this example instead of something like inline-block.
Answer: I used table instead of inline-block because display context such as block and table are used as containing elements and do not group. Display context like inline-block and inline-table are used for child elements that are meant to be grouped together. It's a small difference but I thought considering form is usually meant as a container table would be more appropriate.

display: inline-block leaves gap with respect to height after div element

I have a div and an image in one div. Parent div has the background color. display: inline-block is given to both child div and the image.
<div style="background-color: black;">
<div style="display: inline-block; width: 20px; height: 105px; background-color: #27ae60; margin: 0;"></div>
<img style="display: inline-block; padding: 0px 10px;" src="http://cdn01.coupondunia.in/sitespecific/media/generated/merchantlogos/logo_5e29580_97.jpg?v=1413531812" />
</div>
jsfiddle link
http://jsfiddle.net/hv9szL92/2/
Gap below ebay image and green block must be removed. Thanks
The gap is because you set child elements as display: inline-block, and inline/inline-block elements respect white spaces, including new-line characters.
The simplest fix is to set zero font-size on the parent container in order to make those white spaces zero sized.
<div style="background-color: black; font-size: 0;">
/* content unchanged */
</div>
Remember to reset font-size back to some reasonable value for any nested element if you need to display text in them.
And it's better not to use inline styles, but I assume this is just an example in your case.
Demo: http://jsfiddle.net/hv9szL92/4/
As asked by OP, "Gap below ebay image and green block must be removed. Thanks"
http://jsfiddle.net/hv9szL92/5/
set the vertical-align property on the image and you're done (see Get rid of space underneath inline-block image) :
<img style="display: inline-block; padding: 0px 0px; vertical-align: top;" src="http://cdn01.coupondunia.in/sitespecific/media/generated/merchantlogos/logo_5e29580_97.jpg?v=1413531812" />
As for the green block, just remove the nested div element
You can just edit the margin of your img
<div style="background-color: black;" >
<div style="display: inline-block; width: 20px; height: 105px; background-color: #27ae60; margin: 0;" ></div>
<img style="display: inline-block; padding: 0px 10px; margin-bottom: -3.1px;margin-left: -13.5px;" src="http://cdn01.coupondunia.in/sitespecific/MEDIA/generated/merchantlogos/logo_5e29580_97.jpg?v=1413531812" />
</div>
Giving the image a negative margin should prove to be helpful
Any problems , let me know
Properly aligned and formatted using CSS-tables and Unordered List.http://codepen.io/anon/pen/WvGJqq
<div id="container">
<ul>
<li id="green-block"></li>
<li id="logo-wrap"><img id="logo" src="http://cdn01.coupondunia.in/sitespecific/media/generated/merchantlogos/logo_5e29580_97.jpg?v=1413531812" /></li>
</ul>
</div>
By using CSS tables you are able to use 'vertical-align: bottom;' to align the image with the bottom of the css cell.
Structure as follows:
- div#container [display: inline-table]
- ul [display: table-row]
- li [display: table-cell, vertical-align:bottom]
- img#logo [display: block, vertical-align:bottom]
Its pure css, but the same concept besides table layout creating from the mid 90's.
/* css reset */
ul {
padding: 0;
margin: 0;
list-style: none;
}
li {
padding: 0;
margin: 0;
width: 0;
}
/* css */
#container {
width: 100%;
height: 105px;
background: #000;
margin: 0;
padding: 0;
display: inline-table;
}
ul {
display: table-row;
}
#green-block {
width: 20px;
height: 105px;
background-color: #27ae60;
margin: 0;
display: table-cell;
}
#logo-wrap {
display: table-cell;
vertical-align: bottom;
}
#logo {
display: block;
vertical-align: bottom;
margin: 0 10px;
}
A really nice article out lying many of the concepts used for CSS tables.
http://colintoh.com/blog/display-table-anti-hero

Inner div floats out of parent div

Example
There is a margin-bottom set for each sidebar-block of 10px, it appears as the inner div which is sidebar-block.body is flowing out of the container.
I researched and debugged and cannot find the cause for this, the only time I use floats is on the main #sidebar itself.
HTML
<div id="sidebar">
<div class="sidebar-block">
<div class="sidebar-block title"><div class="text-with-margin">profile</div></div>
<div class="sidebar-block body"></div>
</div>
<div class="sidebar-block">
<div class="sidebar-block title"><div class="text-with-margin">forum activity</div> </div>
<div class="sidebar-block body"></div>
</div>
</div>
CSS
#sidebar {
float: right;
width: 268px;
margin-top: 10px;
}
.sidebar-block {
margin-bottom: 10px;
}
.sidebar-block.title {
background-color: #2E392F;
min-height: 47px;
color: white;
font-size: 1.2em;
}
.sidebar-block.body {
overflow: hidden;
background-color: white;
}
.text-with-margin {
width: 100%;
padding: 0.5em 0.5em 0.5em 0.5em;
display: block;
}
Fixed, it was because I used .sidebar-block title, .sidebar-block body in a way so that the css for .sidebar-block would automatically be applied to them, not my intention so I renamed the divs.
According to your comment. Change your code for that
#sidebar > .sidebar-block
{
margin-bottom: 10px;
}
Demo: http://jsfiddle.net/fvjw5/1/
You have to set the maximum width of the Sidebar element.
As it is, the Sidebar element does not have a fixed size, which will nullify the
.text-with-margin {
width: 100%; // The width. You should change this.
...
}
See this post for information about position: CSS Positions
You should try something like:
#sidebar {
width: 100%; // Or whatever size you want the sidebar to be.
position: relative; // You can play with this for different results.
...
}
You can look at the information provided on the answer below:
Responsive web design