Why negative right margin not work? - css

Since the edge of an element with margin-left: -10px crosses the edge of its parent, why doesn’t the same happen with margin-right: -10px?
example
div {
background: red;
width: 200px;
height: 100px;
}
p {
background: blue;
width: 100%;
}
.left {
margin-left: -10px;
}
.right {
margin-right: -10px;
}
<div>
<p class="left">Hello</p>
</div>
<div>
<p class="right">Hello</p>
</div>

The good news is that negative margins do work!
To see negative margins at work, consider the following code snippet:
.wrapper {
outline: 1px solid blue;
padding: 40px;
}
.content {
outline: 1px solid red;
background-color: #D8D8D8;
}
.content p {
outline: 1px dotted blue;
background-color: rgba(255, 255, 0, 0.3);
margin: 0 0 0 0;
text-align: justify;
}
.content p.lefty {
margin-left: -20px;
}
.content p.righty {
margin-right: -20px;
}
<div class="wrapper">
<div class="content">
<p>Lorem ipsum dolor sit amet, ...</p>
<p class="lefty">Sed ipsum ante, dictum vel rhoncus id, ...</p>
<p class="righty">Curabitur aliquam tristique mattis...</p>
</div>
</div>
I added outline's to all the div's and p's to show the extend of the content boxes.
The first paragraph has zero margins and I offset one paragraph to the left and the other to the right.
If you have enough content to fill the width of the paragraph (or if you show the outlines), you will see the text box flow outside of the content box. You can also see from the paragraph outline's that the text does extend to the left and to the right.
However, to see the effect on the right, you need enough content to fill in the full width of the paragraph or you need to set a background color or outline on the child element.
If you start fixing the width and height, on content, you will see other effects such as the paragraphs flowing outside of content.
Studying this simple code structure illustrates many facets of the CSS box model and it is illuminating to spend some time with it.
Fiddle Reference: http://jsfiddle.net/audetwebdesign/2SKjM/
If you remove the padding from the wrapper, you may not notice the right margin shift because the elements will extend to fill the full width of the parent container or the page width depending on the specific details of the HTML/CSS.
Why Did My Example Not Show the Effect!!!???
In your example, you did not see the effect because you fixed the width of the p elements by specifying width: 100%, which directs the paragraph to take the width of the
parent container (200px in your example).
If you make a simple change to the width from 100% to auto:
p {
background: blue;
width: auto;
}
you will see your second paragraph just out to the right as you expected.
Note: Outline vs Border
Also, note that the red box is due to the outline, which encloses the text boxes within the content, even when the text boxes extend outside of the parent (content) element. As a result, the outline box can be much bigger than the border box of the corresponding element.

It's because elements are laid out from left-to-right by default not right-to-left. You can see the opposite effect when you float the <p>s right.
jsFiddle
.right {
margin-right: -10px;
float:right;
}

Simply, just change this css :
p {
background: blue;
width: 100%;
}
to:
p {
background: blue;
display: block;
}
Here the demo : http://jsfiddle.net/pVKNz/
If you want to made like shifting elements, use this css:
.left {
margin-left: -10px;
margin-right:10px;
}
.right {
margin-right: -10px;
margin-left:10px;
}

If there is someone wants to give negative margin-right to flex box,
Please consider justify-content: space-between.
HTML
<div class="parent">
<div class="child">
</div>
<div class="child negative-margin">
</div>
</div>
CSS
.parent {
box-sizing: border-box;
/* please concentrate on flex, space-between */
display: flex;
justify-content: space-between;
background-color: blue;
width: 500px;
height: 200px;
border: 5px solid red;
}
.child {
box-sizing: border-box;
display: inline-block;
width: 50%;
background-color: yellow;
}
.negative-margin {
background-color: cyan;
margin-right: -250px;
}

Related

Text occupying more space than needed using flexbox

I'm trying to draw a square next to a multiline piece of text in a fixed width container for a color legend. However, I'm running into the issue that even though the text and the square should fit in the container, the square is getting squashed into a rectangle as the text element takes up more horizontal space than it should. Is there a way I can (preferably without hard-coded magic numbers) ensure that the p element only takes the horizontal space it needs to display the text?
Relevant MWE:
html:
<div class="div">
<div class="square">
</div>
<p class="text">
Lorumipsum dolorsitamet
</p>
</div>
css:
.div {
width: 140px;
display: flex;
align-items: center;
outline: 1px solid blue;
}
.square {
width: 25px;
height: 25px;
background-color: red;
}
.text {
margin-left: 2px;
outline: 1px solid red;
}
Fiddle:
http://jsfiddle.net/6jxtp8k5/59/
Use min-width and min-height instead of using width and height. This will ensure that the square will always have the specific width and height.
.square {
min-width: 25px;
min-height: 25px;
background-color: red;
}

Blockquote styling breaks float-left div?

I have two divs on a page. Div #1 is floated left and contains an image and some text. The text in div #2 wraps around it nicely, as I expect. But when there's a blockquote with some styling in div #2, the styling extends into div #1. This isn't what I want.
I'm sure I'm missing something super basic, but I can't figure out what it is.
In this sample, I don't want the red going into the gray.
.floatl {
float: left;
height: 200px;
width: 100px;
background: #CCCCCC;
opacity: 0.5;
margin-right: 2px;
}
blockquote {
border-bottom: 3px solid red;
border-top: 3px solid red;
}
<div class="floatl"></div>
<div>
<p>This is some text here.</p>
<blockquote>This is a quote.</blockquote>
</div>
I'm looking to either a) get div #2's non-text content to respect div #1 or b) discover another way to float div 1 to the left.
Thanks for your help!
Wrap the divs in a new div and apply display:flex so it will become the flexbox container.
.new-wrapper {
display: flex;
}
Your main content, which is now a flex item along with the .float1 div, will want to shrink up. I gave the content div a class and told it to grow to fill the rest of the flex container:
.main-content {
flex-grow: 1;
}
Remove the float and now you are good.
.new-wrapper {
display: flex;
}
.floatl {
height: 200px;
width: 100px;
background: #CCCCCC;
opacity: 0.5;
margin-right: 2px;
}
.main-content {
flex-grow: 1;
}
blockquote {
border-bottom: 3px solid red;
border-top: 3px solid red;
}
<div class="new-wrapper">
<div class="floatl"></div>
<div class="main-content">
<p>This is some text here.</p>
<blockquote>This is a quote.</blockquote>
</div>
</div>

Negative margin bottom to footer doesn't work

I'm trying to move the footer down 50px to go outta screen,
but the negative margin doesn't work (nothing is moving) and I'm not quite sure why...
footer {
background: #111;
padding: 50px 0 100px;
text-align: center;
margin-bottom: -50px;
}
Here's an example
body {
background: white;
margin: 0;
}
section {
height: 100vh;
}
footer {
background: green;
padding: 50px 0 100px;
text-align: center;
color: white;
margin-bottom: -50px;
}
<body>
<section>
Section 1
</section>
<section>
Section 2
</section>
<footer>
<div>
some content here
</div>
</footer>
</body>
Negative margin is working fine but it's not doing what you are expecting. negative margin-bottom will not make the element to move outside. It will make the parent element to shrink instead.
Here is a simplifed example:
.box {
border:5px solid #000;
}
.box div{
background:red;
height:200px;
margin-bottom:-50px;
}
<div class="box">
<div></div>
</div>
As you can see the parent element has a height less than its child due to negative margin and we are having an overflow.
This is what is happening in your case, and since the overflow is by default scroll you will keep seeing the footer. Add some border and you will better see:
body {
background: white;
margin: 0;
border:2px solid;
}
section {
height: 100vh;
}
footer {
background: green;
padding: 50px 0 100px;
text-align: center;
color: white;
margin-bottom: -50px;
}
<section>
Section 1
</section>
<section>
Section 2
</section>
<footer>
<div>
some content here
</div>
</footer>
In order to hide the overflowing part, simply adjust the overflow property and you will have what you want:
html {
overflow:auto;
}
body {
background: white;
margin: 0;
border:2px solid;
overflow:hidden;
}
section {
height: 100vh;
}
footer {
background: green;
padding: 50px 0 100px;
text-align: center;
color: white;
margin-bottom: -200px;
}
<section>
Section 1
</section>
<section>
Section 2
</section>
<footer>
<div>
some content here
</div>
</footer>
As you can see, I have added a bigger negative margin to shrink more the body element and to make all the footer outside then I hide it using overflow:hidden
use transform instead of margin
footer {transform: translateY(-50px);}
If I understood your question right, you want a footer to be half hidden from the view.
If so, try to use fixed position, add this to your css:
position: fixed;
bottom: -50px;
If you are using Firefox, try hitting the F12 button for the Web Developer tool.
In the inspector tab you can inspect the element and set the css rules for that element.
Probably you have some kind of conflict with rules declared somewhere else.
You can change live the css for testing in the Web Developer -> Inspector -> Stiles.
For positioning use position and top/bottom/left/right. For example
position: relative;
bottom:50px;

Make floating div 100% height of parent that uses min-height, while still allowing parent to expand

I'm trying to create a list of items where each item in the list contains essentially two columns ... the left column some text, and the right column 2 buttons for yes/no. I want the two buttons on the right to be vertically aligned with the text. For aesthetic reasons, I want a min-height on the list item. I finally figured out that a floating div must be inside an absolute div for the 100% height to work. The problem is now that I have an absolute div inside my original relative div, it no longer expands to accommodate text longer than min-height. I've read so many articles and tried so many different combinations of height/relative/absolute/float/clear/overflow and nothing has worked for my situation. Is there a solution to this?
In my example here http://jsfiddle.net/THBFY/4/ I need the red box to be the same height as the blue box so that the vertical align works.
<div class="list_container">
<div class="list_item">
<div class="item_text">
My text in this item. This could be a variable length creating a div ranging from about 75-150px in height. This is a lot of text to make it longer although I am not really saying anything here. It is only to make the blue box taller than the red box.
</div>
<div class="item_buttons">
<div class="buttons_inner">
<div class="button button_yes">Y</div>
<div class="button button_no">N</div>
</div>
</div>
</div>
</div>
.list_container { position: relative; width: 400px; }
.list_item { position: relative; min-height: 70px; overflow: hidden; border: #000000 solid 1px; }
.item_text { float: left; width: 340px; background-color: #0066BB }
.item_buttons { display: table; float: right; width: 50px; height: 100%; background: #FF0000; }
.buttons_inner { display: table-cell; vertical-align: middle; }
.button { display: block; margin-left: auto; margin-right: auto; height: 40px; width: 40px; background-repeat: no-repeat; }
.button_yes { background-image: url("images/yes.gif") }
.button_no { background-image: url("images/no.gif") }
When I add in the inner div with position:absolute http://jsfiddle.net/THBFY/5/ the problem is the height no longer increases to show all of the text.
<div class="list_item_inner">...
.list_item_inner { position: absolute; height: 100%; }
But if I now change the min-height of the outer div from 70 to 200 http://jsfiddle.net/THBFY/6/, you can see that the 100% height on the red box is in fact working, so my problem is either in the first situation without the absolute position, I need the red box to stretch, or in the 2nd situation with the absolute div, I need the container to stretch.
HTML:
<div class="list_container">
<div class="list_item">
<div class="item_text">My text in this item. This could be a variable length creating a div ranging from about 75-150px in height. This is a lot of text to make it longer although I am not really saying anything here. It is only to make the blue box taller than the red box.
</div>
<div class="item_buttons">
<div class="buttons_inner">
<div class="button button_yes">Y</div>
<div class="button button_no">N</div>
</div>
</div>
</div>
</div>
CSS:
.list_container { position: relative; width: 400px; }
.list_item { border: #000000 solid 1px; display:table; }
.item_text { display:table-cell; width: 340px; background-color: #0066BB }
.item_buttons { display:table-cell; width: 50px; background: #FF0000; }
.button { display: block; margin-left: auto; margin-right: auto; height: 40px; width: 40px; background-repeat: no-repeat; }
.button_yes { background-image: url("images/yes.gif"); }
.button_no { background-image: url("images/no.gif"); }
fiddle

Div with 100% width inside a centered div with dynamic width?

I'm not sure how to make this work crossbrowser-wise, so I need some of your expertise ;)
How do I make styling that looks like this and works crossbrowser-wise? (IE7 as well)
http://imageshack.us/photo/my-images/543/examplek.jpg/
The red box has a fast defined width
The green box is centered inside the red box and has a dynamic width + a padding/border
The blue box is a "mouseover" div which needs to have the same width as the green box (without the padding/border)
Here is one way to achieve this (with a dynamic width for green box): http://jsfiddle.net/nKdt6/
HTML
<div class="outer">
<div class="inner">
<p>
lorem ipsum
<p>
<div>
<p>Blah blah blah</p>
</div>
</div>
</div>
CSS
.outer {
background-color : red;
text-align: center;
width: 500px;
}
.inner {
background-color: lime;
border: 3px black solid;
display: inline-block;
padding: 20px;
*display: inline;
*zoom: 1;
position: relative;
margin: 100px 0;
border-radius: 10px;
overflow: hidden;
}
.inner > div {
display: none;
background-color: aqua;
position: absolute;
bottom: 0;
left: 0;
right: 0;
}
.inner:hover > div {
display: block;
}
To center the .inner element when it has a dynamic width we can use text-align: center in .outer and display: inline-block in .inner. I have added the extra CSS *display: inline and *zoom: 1 to make this work in IE7 as it does not support display: inline-block.
Edit
To get a thin black outline (outer border) around a wide white inner boder (as achieved and demonstrated by #DonPedro in the comments below), you can add a second border to an inner child element that controls the full height and width of the parent element. In the example above, this is .inner > p.
CSS
.inner {
...
border: 1px black solid;
...
}
.inner > p {
...
border: 10px solid white;
...
}
Working JSFiddle: http://jsfiddle.net/nKdt6/1/ (provided by #DonPedro)
This cannot be achieved using outline due to the border-radius styling, and as far as I am aware Mozilla is the only browser that supports any type of outline radius (-moz-outline-radius).

Resources