When I have inline-block parent and child elements IE shows ghost space between them:
I can fix this by removing the whitespace in the html but I want to know if there is a css cross-browser solution for this.
.bar {
height: 30px;
}
.section {
display: inline-block;
height: 100%;
background: red;
}
.section::before {
content: "";
display: inline-block;
height: 100%;
vertical-align: middle;
margin-left: -.25rem;
}
span {
background: green;
display: inline-block;
vertical-align: middle;
}
<div class="bar">
<div class="section">
<span>
IE ghost
</span>
</div>
<div class="section">
<span>
No ghost
</span><!--
--></div>
</div>
This occurs because of the inline behaviour of the inline-block. They are treated like other inline elements where surrounding sibling elements (including spaces, text, etc.) Will be parsed as opposed to ignored.
As you stated, one solution is to remove the white-space between the affected divs which can mess with your html formatting (if you care about that).
Solution using CSS.white-space:
If you are sure that you will not require the contents of the containing div.bar to wrap then you can set the CSS property of
.white-space to nowrap:
.bar {
height: 30px;
white-space: nowrap;
}
Related
I am trying to break a text by word if possible, and if not - break anyways so the layout isn't dying. This works by default in google chrome and wraps properly, but it doesn't work in firefox.
.a {
width: 200px;
word-wrap: break-word;
display: inline-block;
white-space: normal;
word-break: break-word;
}
.a>div {
text-align: left;
display: inline-block;
}
<div class="a">
<div>
achrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachri
</div>
</div>
http://jsfiddle.net/prswjktc/12/
The problem can be solved by adding max-width: 100%; in the case in the fiddle but I am looking for alternative solutions. (I can't remove the inner div either).
Here we go :-)
Put your words (or terms) into <span>s.
set to
display: inline-block (so they get all the width they need)
max-width: 100%; overflow: hidden (so, yes, there's a chop-off, if column exceed)
overflow-wrap: break-word (so he breaks if there's a chop-off
legacy backup (think -moz-whatever): word-wrap: break-word
code:
span
display: inline-block
max-width: 100%
overflow-wrap: break-word
word-wrap: break-word
full Codepen
You can use the CSS3 property overflow-wrap, which may be what you're looking for. Read more at MDN, including about browser support, but the gist is that "In contrast to word-break, overflow-wrap will only create a break if an entire word cannot be placed on its own line without overflowing."
Note also that the width of 200px you have is not on the div that contains the long text but on the .a parent div, and that the div with the long text has display: inline-block, so currently its width will be determined by its content and it will spill out of the fixed-width .a parent div. To fix this, either give the inner div (.a > div) an explicit width (could be 200px, or 100%, or whatever your layout actually requires), or make the inner div display as a block by removing display: inline-block and/or setting display: block explicitly.
Here's a working snippet, in which I've left .a > div as an inline-block, and created another div .b where .b > div is a block:
.a {
width: 200px;
word-wrap: break-word;
display: inline-block;
white-space: normal;
word-break: break-word;
}
.a>div {
text-align: left;
width: 100%;
display: inline-block;
overflow-wrap: break-word;
}
.b {
width: 200px;
display: inline-block;
white-space: normal;
}
.b>div {
text-align: left;
display: block;
overflow-wrap: break-word;
}
<div class="a">
<div>
achrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachri
</div>
</div>
<div class="b">
<div>
achrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachri
</div>
</div>
Add word-break:break-all; to the child selector (.a > div)
https://jsfiddle.net/f4bdx7z9/1/
.a {
width: 200px;
word-wrap: break-word;
display:inline-block;
white-space:normal;
word-break:break-word;
}
.a > div {
text-align:left;
display:inline-block;
word-break:break-all;
}
<div class="a">
<div>
achrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachri
</div>
</div>
Given the following CSS declarations used to create a responsive grid of squares:
nav a {
display: block;
float: left;
overflow: hidden;
padding-bottom: 25%;
width: 25%;
}
nav a p {
display: none;
}
nav a:hover p {
display: block;
}
overflow: hidden is not being respected when the child element is displayed. The child appears to extend the height of the parent and pushes the element below its parent out of place.
I'm pretty sure this is a result of using the padding-bottom/percentage hack I'm using to achieve flexible squares, as everything works as expected when using fixed heights.
Is there a workaround? Is there a different technique I should be using?
Fiddle
You are correct in that the padding-bottom is causing the fifth element out of place. When you hover over your <a>, the height of the element is increased by the height of the revealed <p> and then an additional 25% padding-bottom is added on top of that hence causing your element below to be shifted right.
To avoid this, we can absolutely position your revealed <p> so that its height is not calculated when adding the padding-bottom.
https://jsfiddle.net/2qaz1dLx/2/
As for whether this is a good idea...probably not, flexbox is pretty well supported in modern browsers nowadays
Add position: absolute to the nav a p class
nav a p {
position: absolute;
display: none;
}
nav {
display: block;
width: 100%;
}
nav a {
display: block;
float: left;
overflow: hidden;
padding-bottom: 25%;
width: 25%;
}
nav a p {
position: absolute;
display: none;
}
nav a:hover p {
display: block;
}
<nav>
<a>
one
<p>one child</p>
</a>
<a>
two
<p>two child</p>
</a>
<a>
three
<p>three child</p>
</a>
<a>
four
<p>four child</p>
</a>
<a>
five
<p>five child</p>
</a>
</nav>
I want a row of images evenly distributed and justified, after some research I've found this elegant method:
#container {
text-align: justify;
background-color: #FF0000;
}
#container img {
display: inline-block;
}
#container:after {
content: "";
width: 100%;
display: inline-block;
}
<div id="container">
<img src="http://placehold.it/150x100" />
<img src="http://placehold.it/100x150" />
<img src="http://placehold.it/250x50" />
<img src="http://placehold.it/150x150" />
</div>
See the result here: http://codepen.io/naio/pen/vbgrm
Why that little margin on the right?
How can I get rid of the empty space added below the images?
You can remove the bottom whitespace using the following adjustments to your CSS:
#container {
text-align: justify;
background-color: #FF0000;
line-height: 0;
}
#container img {
display: inline-block;
}
#container:after {
content: "";
width: 100%;
display: inline-block;
vertical-align: bottom;
}
The generated content from the pseudo-elememt (empty string) creates an inline box that has a height equal to the line height of the containing block (#container in this example).
By setting line-height: 0, this forces any inline boxes to shrink to zero height.
Footnote
In Chrome (and similar webkit browsers), you will see some extra space to the right of the right-most element on the line. This extra space is not seen in Firefox (where I tested the code).
The extra space is the result of the white space in the original HTML mark-up. The right-most element has a white space character (CR/LF) before the closing </div> tag and this generated content is placed after the white-space, which shows up in some browsers.
You can get rid of it by modifying the HTML as follows:
<div id="container">
<img src="http://placehold.it/150x100" />
<img src="http://placehold.it/100x150" />
<img src="http://placehold.it/250x50" />
<img src="http://placehold.it/150x150" /></div>
that is, keep the closing </div> tag right next to the final img tag.
If you put some text in the #container:after's content property you will notice what it does
#container {
text-align: justify;
background-color: #FF0000;
}
#container img {
display: inline-block;
}
#container:after {
content: "This is some text";
width: 100%;
display: inline-block;
}
http://www.w3schools.com/cssref/sel_after.asp
Check out this link for more details. #container:after adds content after everything else in the container is loaded.
One way to solve your problem is to set the container's height to 150px, but that's not a very flexible solution. If I were you I wouldn't use these styles. When you create a div and not set it's width and height it resizes automatically to fit it's children. Somehow the #container:after is blocking this feature. Just use something else :)
another approach that doesn't have this whitespace & padding issue would be:
http://jsfiddle.net/eNKhy/3/
#container {
text-align: justify;
-ms-text-justify: distribute-all-lines;
text-justify: distribute-all-lines;
}
.stretch {
width: 100%;
display: inline-block;
font-size: 0;
vertical-align: bottom;
}
#container, #container img, .stretch{
line-height:0;
}
and add <span class="stretch"></span> in the end of your div
I am coding a page with a banner at the top which should contain a series of buttons. The following code works in all but the buttons are taking a new line when they should appear side by side. I know that div automatically takes a new line and that I should use span, but when I do it doesn't stretch the banner to fit the button like it does with a div. I have tried using several variations of float but to no avail.
<style type="text/css" media=screen>
body{
margin: 0px;
padding: 0px;
color: #000;
font-family: helvetica, times;
font-size: 14px;
}
#wrapper{
position: absolute;
height: 100%;
width: 100%;
text-align:center;
}
#banner{
background: url('images/banner_background.png');
position: relative;
margin: 0;
width: 100%;
color: #FFFFFF;
z-index: 3;
}
#banner #button {
padding:10px;
margin:auto;
position: relative;
background: url('images/button.png');
height: 100%;
z-index: 4;
width:100px;
}
</style>
</head>
<body>
<div id="wrapper">
<div id="banner">
<div id="button">
dfsdfsfdsdfs
</div>
<div id="button">
sddfdfdsf
</div>
</div>
</div>
To have the padding still work on an inline element like a span, you would have to set it to display: inline-block - it will still be in the text flow, unlike block elements, but accept width/height, padding and margin the same way an image does. Images are inline-blocks by default.
CSS:
#banner .button {
display: inline-block;
padding:10px;
margin:auto;
position: relative;
background: url('images/button.png');
height: 100%;
z-index: 4;
width:100px;
}
HTML:
<span class="button">
sddfdfdsf
</span>
<span class="button">
sddfdfdsf
</span>
Important: IDs are unique to a single element. If you have multiple buttons, use classes. I adjusted that as well.
Make your <div>-s inline-block - DEMO
Also ID-s should be unique.
And if you need buttons, then you have to use the <button> tag - it just makes more semantic sense. And it can be styled anything you want - DEMO
You should use display: inline for a div rather than using a span.
div set the display to be block by default, while span to be inline. You can't set padding or margin values to span because it is designed to be used in a lighter way (e.g., underline or italic for some words). So it's better to use div if you can do so and set attributes like display: inline to meet with the special needs.
This may sound weird but i have some css which aligns mys divs. In one place i also use http://www.brunildo.org/test/img_center.html which centers images.
Now i want my divs inside a larger div to go to another line if this one gets full. float: left seems to be the answer. The problem is it ruins my formatting. Including solution in the above link. I have this test code. If i remove the width and float it looks fine except it may take up too much space and not go to another line.
I was thinking i could use float on an outerdiv and center the image within. However float: left is still breaking it. I am hoping there is a way to remove the float so each div does go left but the div inside centers correctly not breaking my formatting.
<style type="text/css">
.wraptocenter {
display: table-cell;
text-align: center;
vertical-align: middle;
width: 200px;
height: 200px;
background: blue;
}
.wraptocenter * {
vertical-align: middle;
}
/*\*//*/
.wraptocenter {
display: block;
}
.wraptocenter span {
display: inline-block;
height: 100%;
width: 1px;
}
/**/
div.c
{
background: red;
overflow: hidden;
min-width: 400px;
max-width: 400px;
}
div.c div
{
float: left;
}
</style>
<!--[if lt IE 8]><style>
.wraptocenter span {
display: inline-block;
height: 100%;
}
</style><![endif]-->
<div class="c">
<div>
<div>
<div class="wraptocenter"><span></span><img src="a.jpg" alt="/a.jpg"></div>
<div class="wraptocenter"><span></span><img src="a.jpg" alt="/a.jpg"></div>
<div class="wraptocenter"><span></span><img src="a.jpg" alt="/a.jpg"></div>
</div></div></div>
regular old display:inline can be used on the images themselves (or a container div). this will let the items flow onto multiple lines depending on the width of the enclosing div.
to center the top-level div, something like margin: 0 auto should do it (if the parent has a width) or the good old <center> tag if not.