I have always thought that the background-image of an element appears in the element itself, its padding and border but not its margin. However, while trying to get something else to work I discovered this seems to not be the case and the background-image is appearing in the margin.
body {
background: url("https://www.google.co.uk/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png");
background-size: contain;
background-repeat: no-repeat;
border-width: 1px;
border-style: solid;
border-color:red;
margin: 50px;
}
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.</p>
https://jsfiddle.net/rz52z14r/
As can be seen, the background is appearing in the margin. Additionally, if I add in overflow: hidden the overflow is not actually hidden. Again, I was under the impression the overflow is anything outside the bounds of the element, i.e., element and padding not including the margin.
So, overall: why is the background image appearing in the margin? And why is the overflow not hidden?
EDIT: there have been a few similar answers to the question; all of which provide a solution to the situation. However, the situation is fictional. What I would like to know is why does this behaviour occur on the <body> tag but not any other tag?
The reason why this occurs is because the root element is treated as a special case when rendering the background. In effect, the background is not being applied to the body but to the canvas:
The background of the root element becomes the background of the canvas and covers the entire canvas, anchored (for 'background-position') at the same point as it would be if it was painted only for the root element itself. The root element does not paint this background again.
The background (http://www.w3.org/TR/CSS2/colors.html#background)
But the root element in this case would be the html element wouldn't it? Well, the following states that it is preferred to apply the background to the body rather than the html element:
For HTML documents, however, we recommend that authors specify the background for the BODY element rather than the HTML element.
The background (http://www.w3.org/TR/CSS2/colors.html#background)
If the background-color and background-image of the html element is transparent and none respectively the rules regarding the canvas apply to the body element instead:
For documents whose root element is an HTML "HTML" element or an XHTML "html" element that has computed values of 'transparent' for 'background-color' and 'none' for 'background-image', user agents must instead use the computed value of the background properties from that element's first HTML "BODY" element or XHTML "body" element child when painting backgrounds for the canvas, and must not paint a background for that child element. Such backgrounds must also be anchored at the same point as they would be if they were painted only for the root element.
The background (http://www.w3.org/TR/CSS2/colors.html#background)
So, to make a background on the body respect the margins simply add a background-color to the html element in CSS:
html {
background-color: red;
}
body {
background: url("https://www.google.co.uk/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png");
background-size: contain;
background-repeat: no-repeat;
border-width: 1px;
border-style: solid;
border-color:red;
margin: 50px;
}
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.</p>
Apply background-image to your container, not to your body.
p {
background: url("https://www.google.co.uk/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png");
background-size: contain;
background-repeat: no-repeat;
border-width: 1px;
border-style: solid;
border-color:red;
margin: 50px;
}
See : https://jsfiddle.net/rz52z14r/9/
I'm not quite sure what you are trying to do but the background image you have is sitting in the .body tag. And not the .Body p
https://jsfiddle.net/rz52z14r/12/
Related
This question already has an answer here:
Media query in responsive email template
(1 answer)
Closed 3 years ago.
I'm setting up an email which contains in the body a picture and some text. On normal computer screens the image is to the left and the the associated text to the right (using inline-block).
This looks like so:
(https://www.flickr.com/photos/183424995#N08/48518551371/in/dateposted-public/)
When the screen size is changed ie. for an i-phone, I'm aiming to get the text to move underneath the image and rather than just having a width of half the screen (as it's inline-block), to take up the whole width of the screen underneath.
What I'm trying to get:
https://www.flickr.com/photos/183424995#N08/48518549646/in/dateposted-public/
What is actually happening:
https://www.flickr.com/photos/183424995#N08/48518724692/in/dateposted-public/
I've created a "main" div containing the image div, and a div containing the text, both inline-block. The "main" div has a width set to 100% and the text div has a min and a max div so it can move from next to the image to under the image depending on screen width.
I've tried rejigging the max width of the text div to be wider, but then the text never remains to the side of the image. And I'm trying to avoid floating anything.
I can't use bootstrap or flexbox as it's an email so am limited to fairly basic CSS.
The JSFiddle is https://jsfiddle.net/cfn76vqz/ to show what kind of responsiveness I have so far. And the general HTML structure is as below.
<div id="main">
<div id="left">
<div >
<img src="https://via.placeholder.com/300x200/0000FF/FFFFF" />
</div>
</div>
<div id="right">
<div >
<span>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</span>
</div>
</div>
</div>
TLDR: I'm stumped on how to make the text div essentially be 100% of the width if underneath the image but also 50% if there's space to have it to the side of the image. As far as I understand it's always going to be limited to 50% as it's part of an inline-block section.
Because you set width with this why it's not fully of width
max-width: 50%;
So... How we can do
We need to use FLEX display
like this
#main {
/*---HERE---*/
display: flex;
flex-wrap: wrap;
/*----------*/
background: yellow;
width: 100%;
}
#left {
background: orange;
}
#right {
/*---HERE---*/
flex-basis: 0;
flex-grow: 1;
min-width: 50%;
/*----------*/
background: green;
vertical-align: top;
}
<!-- YOUR OLD CODE -->
<div id="main">
<div id="left">
<div>
<img src="https://via.placeholder.com/300x200/0000FF/FFFFF" />
</div>
</div>
<div id="right">
<div>
<span>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</span>
</div>
</div>
</div>
if you want to learn about flex ...more here
you can use viewport units like width: 100vw and height: 100vh for make it responsive depending upon height and width of display.click here
So here is what I am trying to accomplish...
I want to place a perfect square that always covers one or possibly both corners without ever going over in the top right corner of a div... no matter the size or dimensions of the div in question that requires the gradient corner effect.
The reason I want to do that is so I can add gradient effects to corners of sections of a website as so many designers are asking me to do.
The simplest way to do it would be with a transparent PNG file of the gradient obviously... and just set it's height, width, max-height, and max-width to 100% and pin it to the top right of the div in question.
I am too stubborn, though!
This should be possible with pure CSS!
I just can't seem to figure out how.
I have tried nesting multiple responsive square divs and rotating them but to no avail.
I think I am just too tired, and will hopefully be able to answer my own question in the morning!
Thanks for reading.
you can use psedu element :after or :before
You can use position absolute logic in CSS.
Try with this concept.
.container {
width: 25%;
position: relative;
background: #ccc;
border: 1px solid #333;
padding: 10px 15px;
}
.corner-element {
width: 42px;
height: 42px;
background: red;
position: absolute;
top: 0;
right: 0;
z-index: 1;
}
<div class="container">
<div class="corner-element"></div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</div>
My goal (note the small grey circle under "BEFORE CLEANSING" and "AFTER CLEANSING"):
WIth this code I can only view a RED SQUARE, not the image (but in firebug I can view that image is properly loaded:
HTML:
<p class="before-after">Before Cleansing</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
CSS:
p.before-after:after{content:"";width:11px;height:11px;background:red url('/../images/template/small-circle.png') no-repeat top left fixed;display:block;margin:0 auto;}
My result:
Of course If I change background color to transparet, I see nothing.
Thank you.
Lose the first / from the image url:
p.before-after:after {
content:"";
width:11px;
height:11px;
background: red url('../images/template/small-circle.png') no-repeat top left fixed;
display:block;
margin:0 auto;
}
Edit:
Also remove fixed from the background properties.
#Catalin is right, that might work better if you remove the /.
For your info, do you know you can achieve the same effect with css only? You can make a circle with css in your p.before-after::after class with the following code:
p.before-after::after {
border-radius: 50%;
background-color: grey;
width: 11px;
height: 11px;
}
I think there is problem with your shorthand notation of background property. Try this instead:
background: red url('../images/template/small-circle.png') 0 0 no-repeat;
background-attachment: fixed;
Here are two snap shots of the problem.
See how the yellow background of the h3 is cut off?
Here is a jsfiddle
Here is the code:
<style>
.OutputDiv {
background-color: lightcyan;
overflow: auto;
border: solid 2px black;
width: 500px;
}
h3 {
margin-top: 0px;
background-color: yellow;
}
</style>
<div class="OutputDiv">
<h3>My Title is Here</h3>
<pre>
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
</pre>
</div>
I know I could probably add another div with a background color to contain the h3, but the h3 is a block level element.
Any ideas?
Even though <pre> is a block level element, the behavior of it's content is different in this case. Since the content must maintain the line breaks and spaces, the <pre> tag uses the attribute white-space: pre; by default. In your case, both the <pre> and <h3> elements behave like block elements, so their width is set by their parent. However, the text inside the <pre> element doesn't follow these rules and overflows, causing the scrollbar to show up on the parent.
In case the you're just using the pre tag for monospace font, you can apply a white-space: normal rule to the <pre> element.
Otherwise, if this HTML structure isn't a requirement, you can add the overflow: auto to the <pre> element instead, and remove it from the wrapper element.
pre {
overflow: auto;
margin-bottom: 0;
}
Edit:
In case you want the entire div to be scrollable, add a wrapper div around the <h3> and <pre>, and set it's display to inline-block. This will force the inner wrapper to take it's width from it's content, and will also force the block level <h3> to match this width. Check out this fiddle for a demo. This does introduce a vertical scrollbar, but removing the margin-bottom from the <pre> should fix that.
Edit 2: Yup, here's the fixed fiddle.
Currently you can solve your problem by defining the width of your h3 tag
demo
Alternatively, you can use
pre{white-space: pre-wrap;}
but this is not showing scroll bar as pre-wrap cathes 100% width and after then it shifts the word below the line.
Correct Way
remove overflow: auto; from your main div and add overflow: auto; to pre
demo
Note:
As pre tag is overwhelming the width 100% the h3 tag is showing the space in your demo.
You can either solve your problem by defining the width for h3 tag or including the tags in between text given in element.
I have 3 divs inside a wrapper div. Inside my wrapper div, my leftmost div is an arrow image I'm using to navigate between sliders using js. The middle div is the slider, and the right div is the right arrow to move to the next slider.
Here's the code for the slider:
<div class="twocol_double">
<div class="btn_left"></div>
<div id="slide_wrapper">
<div class="slide" style="position: absolute; top: 0px; left: 0px; display: block; z-index: 3; opacity: 1;">
<h3>Heading1</h3>
<p>“Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in vol</p>
</div>
</div>
<div class="btn_right"></div>
</div>
There will be multiple slide classes, but for the sake of the question I only added 1.
For some reason though, my right div with my right arrow is being pushed down. Looking at it in Chromes element inspector there is a 50px right margin on my slider div that I'm not defining anywhere (I see the orange color, but there's no CSS markup for it).
I've recreated the problem in jsfildde here: http://jsfiddle.net/maZbF/1/
I want that right arrow to line up with the other two divs. I've wrecked my brain trying to figure this out and debug it in chrome with no avail. Am I missing something simple?
In order for floated content to stay on the same line, all floated content has to be defined before any normal content.
In this case, you have your left button floated to the left first, which works because it was first. Then you have your division which is not floated and is display: block. A block-level element will always push anything after it down to the next line, even if you define a width for it. So when it gets to your right button after that, it is starting on a new line and floating to the right of that new line. It's starting 131px down from the top, since your division before that has a height: 131px defined on it (and the other content inside it is just overflowing past the boundaries, not interfering with your right-floated element).
So, you have a couple options:
Define your right button immediately after the left button.
Float all three elements to the left so they stack on top of each other.
I think the issue you're having is that your right div is position:relative while the left is position:absolute. I think you can simplify this layout using simple floats though:
HTML
<div class="twocol_double">
<div class="btn_left"></div>
<div id="slide_wrapper">
<div class="slide">
<h3>Heading1</h3>
<p>“Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in vol</p>
</div>
</div>
<div class="btn_right"></div>
</div>
CSS
.twocol_double {
width: 500px;
float: left;
font-size: 1.2em;
}
.btn_left {
cursor: pointer;
display: block;
width: 20px;
height: 170px;
float: left;
background: #ccc url("http://i.imgur.com/7bYsZJD.gif") no-repeat center center;
}
#slide_wrapper {
width: 460px;
height: 131px;
display: block;
float:left;
}
.btn_right {
cursor: pointer;
width: 20px;
height: 170px;
float: right;
background: #ccc url("http://i.imgur.com/0QRkQ2M.gif") no-repeat center center;
}
h3 {
font-size: 1.5em;
color: #7DAC20;
}
p, blockquote {
padding-bottom: 20px;
font-size: 1.3em;
color: #636B75;
line-height: 20px;
}
http://jsfiddle.net/Eb3TA/