I have the following container holding both an image and a text element.
<div class="container">
<img id="image" src="http://dummyimage.com/200">
<span class="text">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</span>
</div>
The desired behaviour is that the div should wrap to the width of the image, and therfore keep the text correctly wrapped underneath. This also needs to be flexible as content is dynamic and image width is not known in advance.
You can do this elegantly enough in Firefox and Chrome using min-content.
.container {
/*Other style stuff up here*/
width: -moz-min-content;
width: -webkit-min-content;
}
Jsfiddle of above - works perfectly in FF and Chrome.
My Problem:
Internet Explorer has no min-content (or equivalent that I can find) which means it is the text not the image which determines the containers width.
Is there any similarly elegant way of achieving this in Internet Explorer?
If not how can i restructure the html/css to allow for cross broser compatibilty for the same behaviour?
As mentioned by someone else you can use -ms-grid-columns. You just add a div around your content with IE only CSS. To other browsers the CSS is ignored and shouldn't affect your layout (unless you're applying CSS to all div elements like padding/margin in which case stop doing that).
HTML
<div id="stupidIE">
<div class="container">
<img id="image" src="http://dummyimage.com/200" alt="">
<span class="text">
Cupcake ipsum dolor sit.
Amet chocolate carrot cake oat cake bear claw croissant.
</span>
</div>
</div>
CSS
.container
{
background-color: #EEEEEE;
border: 1px solid #888888;
padding: 0.3em;
width: -moz-min-content;
width: -webkit-min-content;
}
#stupidIE
{
display: -ms-grid;
-ms-grid-columns: min-content;
}
Here's the JSFiddle: http://jsfiddle.net/LRYSp/
Tested in Chrome and IE11. But it should work in other browsers. However I don't think it will render correctly in IE9 and below.
#Stack_of_Pancakes solution is lacking in that it adds an extra div which is a block element and spans the entire width, whereas the original width:min-content doesn't have this flaw.
It can be fixed:
HTML: (intact)
<div class="container">
<img id="image" src="http://dummyimage.com/200" alt="">
<span class="text">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</span>
</div>
CSS:
.container {
background-color: #EEEEEE;
border: 1px solid #888888;
padding: 0.3em;
width: -moz-min-content;
width: -webkit-min-content;
display: -ms-inline-grid;
-ms-grid-columns: min-content;
}
.container > span:nth-child(2)
{
-ms-grid-row:2;
display:inline-block;
}
http://jsfiddle.net/L28s7txr/6
a bit of jquery?
$(function() {
$('.container').width($('img#image').width());
});
FIDDLE
Related
PURPOSE
Having an editable div in which the text flows in different "simulated" pages, so to obtain an effect like Word. At the moment, I'm interested to have this working in Chrome (no crossbrowser compatibility).
WHAT I'VE DONE
I've created an editable div (pagina) already filled with some text. Inside this div there are 2 divs: block1 and block2.Block1 is a floating right div that simulates the page height.Block2 is a floating left div that simulate the space between pages.The effect I've obtained is a long text "broken" into pages. In my code I've used different background colors to have a better view of the various divs.
THE PROBLEM
When I move the cursor at the beginning of a new "page" and I press [return] more times, the new lines are moved at the right side of the above block2 div (the pages sepatator). If I type something, single letters appears in the right side (see screenshot below).
Problem screenshot
In this Fiddle (http://jsfiddle.net/n4d2jtd9/4/) you can see my experiments result.
.pagina {
width: 200px;
background-color: #AAA;
}
div.block1 {
float: right;
width: 100px;
height: 100px;
background-color: #CCC;
}
div.block2 {
float: left;
width: 200px;
height: 100px;
background-color: #FFF;
}
<body>
<div class="pagina">
<div class="block1"></div>
<div class="block2"></div>
<div class="block1"></div>
<div class="block2"></div>
<div contenteditable="true" style="width:90px;background-color:#DDD;word-break:break-all;">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec libero mi, tempus in tincidunt vitae, aliquet nec nibh. Integer egestas leo vel orci
</div>
</div>
</body>
THE QUESTION
Is there a way to prevent that text effect?
CONSIDERATIONS
When you press [enter] inside an editable div, Chrome adds a div tag per paragraph (and a br tag when you press [enter]+[shift]).
The created "empty" div is always <div><br></div>. Having a zero width, the floating div moves this tag to right. I've noticed that if I put a space char inside the div, it works properly. Maybe jQuery can help.
New Code: based on browsers:
working demo: http://jsfiddle.net/n4d2jtd9/9/
HTML
<body>
<div class="pagina">
<div class="block1"></div>
<div class="block2"></div>
<div class="block1"></div>
<div class="block2"></div>
<div id="editable" contenteditable="true" style="width:90px;background-color:#DDD;word-break:break-all;
">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec libero mi, tempus in tincidunt vitae, aliquet nec nibh. Integer egestas leo vel orci
</div>
</div>
</body>
CSS
#editable{white-space:normal}
}
/* Chrome 29+ */
#media screen and (-webkit-min-device-pixel-ratio:0)
and (min-resolution:.001dpcm) {
#editable{white-space:pre-line;}
}
/* Chrome 22-28 */
#media screen and(-webkit-min-device-pixel-ratio:0) {
.selector {-chrome-:only(;
#editable{white-space:pre-line;}
);}
}
https://jsfiddle.net/9nh220q2/1/
Basically, I have something like this:
<div class="container">
<div class="left">
<img src="http://i.imgur.com/bWQUX0O.jpg" class="image" />
<span>0.3 mi</span>
</div>
<div class="right">
<h3>TITLE HERE</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum nec turpis eu mi nullam sodales.</p>
</div>
</div>
However, these items are inside of a scrolling panel. So, in the jsFiddle I have put these inside of a parent div with width of 600px. As you can see, the <div class="right"> is going below. How can I stop it from doing that?
Calculated width of .right
.right {
width: calc(100% - 120px);
}
.container {
background-color: #fff;
padding: 20px 20px 10px 20px;
overflow: hidden;
border-bottom: 1px solid lightgray;
margin: 0;
}
.left {
width: 100px;
float: left;
margin: 0;
text-align: center;
}
.image {
height: 100px;
width: 100px;
border-radius: 4px;
margin-bottom: 5px;
}
.right {
float: left;
padding-left: 20px;
width: calc(100% - 100px - 20px); /* all width - size of image - padding) */
}
h3 {
margin: 0;
}
<div style="width: 600px">
<div class="container">
<div class="left">
<img src="http://i.imgur.com/bWQUX0O.jpg" class="image" />
<span>0.3 mi</span>
</div>
<div class="right">
<h3>TITLE HERE</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum nec turpis eu mi nullam sodales.</p>
</div>
</div>
<div class="container">
<div class="left">
<img src="http://i.imgur.com/bWQUX0O.jpg" class="image" />
<span>0.3 mi</span>
</div>
<div class="right">
<h3>TITLE HERE</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum nec turpis eu mi nullam sodales.</p>
</div>
</div>
<div class="container">
<div class="left">
<img src="http://i.imgur.com/bWQUX0O.jpg" class="image" />
<span>0.3 mi</span>
</div>
<div class="right">
<h3>TITLE HERE</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum nec turpis eu mi nullam sodales.</p>
</div>
</div>
</div>
You can fix this by removing all float and using flexbox. Flexbox is a powerful modern way to handle this kind of layout. flexboxfroggy is a great way to learn about them.
.container {
display: flex;
justify-content:space-between;
}
Demo
An even better way would be to use standard css grid, but we should wait a bit more.
Edit:
All modern browser support flexbox. For old one, you can use a polyfill if you have to.
You need to set the width of .right to a maximum of 440px. See the working fiddle.
Explanation:
Your container div has a width of 600px. For the elements contained within to line up properly, their widths must add up to a maximum of 600px.
Your img already takes up 100px of that. That means that your div.right can have a maximum width of 500px. (Because 600px - 100px = 500px)
However, if you do set it at 500px, you'll most likely notice that the issue won't be solved. This happens because, by default, most (if not all) browsers render the page using the content-box model which includes the padding and margins of the elements when calculating their widths.
In your case, your containing div has 20px of padding in both sides. In addition, your div.right has 20px of padding on the left. This adds up to 60px which you need to subtract from your available space that we calculated above, 500px. That leaves you with 440px and if you set that as the width of div.right, you'll notice that the elements line up perfectly!
You can also change the default way in which the browser sees the box model by changing the value of box-sizing from content-box to border-box (neither padding nor margins are not calculated in width) or to padding-box (padding is not calculated in width) and then adjust padding, border or width values accordingly.
Until recently I have been using Flexbox to vertically align elements like so:
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-ms-flex-align: center;
-webkit-align-items: center;
-webkit-box-align: center;
align-items: center;
However I have begun working on more and more projects that need to support older browsers which do not support Flexbox e.g. Internet Explorer 8. I would like to begin supporting a much wider range of browsers and devices.
My question is; what are some of the most heavily supported methods of vertical alignment using just HTML and CSS?
In most cases the elements I'm centring will not have fixed heights or widths, generally the width will be a percentage value and the height will be determined by dynamic content.
Thanks in advance.
If you don't have the luxury of knowing the exact size of the box you want to align to the middle, then I usually go with the display:table-* css setup.
Putting the content box into a div with display:table-cell wrapped in a display:table element does the trick.
This solution's browser compatibility is pretty good.
Html
<div class="popup">
<div class="popup-table">
<div class="popup-table-cell">
<div class="popup-body">Hello there!</div>
</div>
</div>
</div>
Css
.popup{position:fixed;top:0;left:0;bottom:0;right:0;}
.popup-table{display:table;width:100%;height:100%;}
.popup-table-cell{display:table-cell;vertical-align:middle;text-align:center;}
.popup-body{display:inline-block;border:1px solid black;padding:3em;}
Uploaded a code example here: http://codepen.io/anon/pen/NdGpje
** Please note, that the .popup class is a wrapper only, you don't have to use it - it's just to have a simple usecase for middle positioning, and a wrapper element for .popup-table.
Here is a very simple example from CSS Tricks. You can set the elements top margin to 50% and then raise it up by half its height. Here is the code:
body {
background: #f06d06;
font-size: 80%;
}
#div1 {
background: white;
height: 300px;
margin: 20px;
width: 300px;
position: relative;
resize: vertical;
overflow: auto;
}
#div1 div {
position: absolute;
top: 50%;
left: 20px;
right: 20px;
background: black;
color: white;
padding: 20px;
transform: translateY(-50%);
resize: vertical;
overflow: auto;
}
<body>
<div id="div1">
<div>
I'm a block-level element with an unknown height, centered vertically within my parent.
</div>
</main>
</body>
The technique I personally use to vertically align content in a div is with display: table; display: table-cell; and vertical-align:middle; like so:
HTML:
<div class="block">
<div class="block__module">
<h1>Title</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec commodo pellentesque est quis mollis. Nulla suscipit risus a ornare viverra. Suspendisse potenti. Phasellus tempor imperdiet ullamcorper. Nam accumsan volutpat tincidunt. Cras eu mauris posuere, imperdiet elit ac, rutrum ligula. Maecenas ullamcorper sit amet nisi vitae consectetur. Sed ultrices lorem a fermentum lacinia.
</p>
</div>
</div>
CSS:
.block {
display:table;
height: 500px;
width:100%;
}
.block__module {
display:table-cell;
vertical-align:middle;
}
Here is a fiddle link with my code.
I understand that your content may be dynamic, I am not sure if changing the height of the div to 100% will help and achieve the same result but this way of vertical alignment works in at least IE8 plus. I always declare a height but I understand that this is not something that we can always do.
I found a similar question to this one on SO that may be of help, please see here.
I also came across this handy code generator that may help, please see here. It gives you the choice of filling in some values and generates the best option for vertical alignment.
I have two p tags
<p style="margin: 0; display: inline;">content1</p>
<p style="margin: 0; display: inline;" align="right">content2</p>
The Output is content1content2. My expectation is like this:
content1 content2
Can anyone help. I want one "content1" in the left p and "content2" in the right 'p'.
You can use CSS flexbox for this. Below is the minimal CSS for the requested layout:
<div style="display: flex; justify-content: space-between;">
<p style="background-color: papayawhip;">Lorem ipsum dolor sit amet.</p>
<p style="background-color: palegoldenrod;">Donec eget luctus lacus.</p>
</div>
For longer content, you can use fixed-width columns:
<div style="display: flex; justify-content: space-between;">
<p style="flex-basis: 49.5%; background-color: papayawhip;">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eget luctus lacus. Cras consectetur elementum mi sed consequat.</p>
<p style="flex-basis: 49.5%; background-color: palegoldenrod;">Pellentesque aliquet condimentum augue in mattis. Praesent sagittis nisl magna, a volutpat arcu imperdiet vel. Quisque et orci sed ligula cursus luctus.</p>
<!-- 49.5% + 49.5% = 99%, remaining 1% is distributed according to justify-content -->
</div>
You could do it with floats:
<p style="margin:0;display:inline;float:left">content1</p>
<p style="margin:0;display:inline:float:right" >content2</p>
The idea of the tag <p></p> is to display a paragraph. So HTML offers you the <div></div> which is a container conecpt. So you should use Salman A's Solution, because there aren't just different tags in html for no reason. Actually you can style a paragraph with css so it is getting displayed the same as a div container, but it is not meant to be like that.
I don't want to say to you, what you have to do. I just wanna help you using the "correct" tags for the things they were made for.
What you really want is something that doesn't assume sufficent width to fit both paragraphs into one line:
* { box-sizing: border-box; }
.two { width: 30em; max-width: 100%; }
.two p { display: inline-block; max-width: 50%; }
.two p:nth-child(1) { float:left; }
.two p:nth-child(2) { float:right; }
<div class="two">
<p>This is the first paragraph of two.</p>
<p>This is the second paragraph of two.</p>
</div>
Here's another quick turnaround to achieve this:
p{
text-align: center;
}
.item p{
display: inline-block;
}
.leftContent{
text-align: left;
width: 50%;
}
.rightContent{
text-align: right;
width: 50%
}
<br>
<!--Use both P tags in the same line without space -->
<article class="item">
<p class="leftContent">Content1</p><p class="rightContent">Content2</p>
</article>
float:left, float:right.... or
width:49.9%;
display:inline;
text-align:left;
text-align:right;
In my fiddle you will see a break in text, I would like to put a <hr> there and decorate it in the CSS, but I have no idea how to do this as when I do this it breaks my inline-block, and I'm thinking that's because the <hr> is a block element. Is there any creative solutions around this? I need it to be fixed there between the two paragraphs of text to maintain responsiveness.
Thanks!
FIDDLE
HTML:
<section>
<div class="first">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut rutrum, nisl id ultricies sollicitudin, neque sapien porta nisl, ut gravida elit quam id nisi. <br /><br />Nunc viverra laoreet porttitor. Duis augue justo, pellentesque a luctus eget, luctus a quam. Fusce nec neque nec dolor mattis tempor id vitae nisi.</p>
<img class="ipad" src="http://img1.lesnumeriques.com/news/26/26963/ipad-4-os.jpg">
</div>
</section>
CSS:
.first {
height: 100%;
line-height: 0;
}
.first p {
vertical-align: middle;
display: inline-block;
width: 49%;
}
.ipad {
vertical-align: middle;
display: inline-block;
width: 49.2%;
}
p {
margin: 0;
padding: 1em 0;
font-size: 1.8em;
line-height: 1.5;
}
You could achieve this by wrapping your <p> and <hr> elements into another <div> element, and making it display:inline-block. My solution involved adding this wrapper so your structure ended up being:
<section>
<div class="first">
<div class="text-wrap">
<p></p>
<hr />
<p></p>
</div>
<img class="ipad" src="http://img1.lesnumeriques.com/news/26/26963/ipad-4-os.jpg" />
</div>
</section>
(Additional element is .text-wrap. Note that I split up the two paragraphs into individual <p> elements.) The CSS I left mostly alone, except I removed the definition for .first p, and added these two:
.text-wrap{
vertical-align: middle;
display:inline-block;
width:49%;
}
.text-wrap p {
vertical-align: middle;
display: inline-block;
}
Here's a JSFiddle example that shows what this achieves. If this isn't what you were looking for, or you wanted to use a different method, let me know and I'll be happy to help further!
Here's an alternative to Serlite's answer. It basically puts the <hr> in implicitly, using CSS.
fiddle
We add a border to the top of each paragraph, except the first one in each container.
p {
...
border-top: 1px solid black;
}
p:nth-child(1) {
border-top: none;
}