Since about a year the multicolumn css3 property matured enjoying support from many browsers. Reason to finally implement it on your website for better design and readability. I thought let's push the envelope and adopt the ancient-but-ever-so-beautiful Drop Caps (=first large initial letter) into the multicolumn. However, certain screen widths break the multicolumn layout in FireFox. What am I doing wrong?
see jsfiddle DEMO
When resizing the window width, you can see the jumping/breaking of the layout in action in IE and Firefox. Below an example. Stuck on whats causing the defects in the multicolumn miss-alignments!?
Sorry for my beardy alter ego selfportrait: I forgot to shave, was staring all day at this problem with no time to tidy up. I promise you though a clean neat shaved portrait back here once this issue is solved!
Above more alignment problems in most screen widths on Internet Explorer 11. Curious Safari and Chrome show the layout faultlessly at all browser screen widths no breakage there.
#multicolumn {
column-count: 3;
-moz-column-count: 3;
-webkit-column-count: 3;
column-gap: 53px;
-moz-column-gap: 53px;
-webkit-column-gap: 53px;
column-rule-color: #EEE;
-moz-column-rule-color: #EEE;
-webkit-column-rule-color: #EEE;
column-rule-style: solid;
-moz-column-rule-style: solid;
-webkit-column-rule-style: solid;
column-rule-width: 1px;
-moz-column-rule-width: 1px;
-webkit-column-rule-width: 1px;
}
#multicolumn p:first-letter{
float:left;
font-weight:normal;
font-size:44px;
margin: 7px 1px 0px 0px;
line-height:27px;
background-color:#AEE;
}
First of all I want to say that the use of the multi column layout module is still not recommendable.
Mainly because of the missing support for the break-before , break-after, break-inside properties, with the exception of IE 10+ and the proprietary -webkit-column-break-* properties (see: CSS3 Multiple column layout).
(You also may want to take a look at my answer to this SO question: IE (11) improper handling of CSS multi-columns?)
Additionally you have to remember, that there is a so called "multi-column pseudo-algorithm", which seems to be confused by your :first-letter selector.
You can avoid this problem by using a span element with a class attribute for the drop caps instead.
But as the first letters are larger in size than the rest of the text, there arises another problem.
It may happen that a (single) line of text of the beginning of a paragraph with a drop cap may fit to the previous column, whereas the drop cap (which is about twice as high as the normal text) may not.
To avoid this unwanted behaviour you have to use another span element, which includes at least more text than that may fit into a single line (of text)!
And giving these span elements a display: inline-block; solves this problem.
Just a word about Amir5000 answer: Though my proposed solution also needs some extra span elements, it does not use "purely presentational markup" which may also produce unwanted empty lines.
But as said at the beginning, using multi-column is at least very "tricky" and very difficult to get predicted results across browsers and/ or different viewport widths.
So here is my proposed "solution": DEMO
The cause of the issue was the float:lefton the #multicolumn p:first-letterif you take that out you will see it no longer has that issue; However you don't have the same format you wanted with the first letter. So I created a JSFIDDLE where I added
#multicolumn p {
float: left;
}
and added a width for the #multicolumn container and centered it as you can see.
Hope that resolves the issue for you.
-------Update---------
So after much time trying to get it to flow as intended I was able to come up with a work around that is pretty simple, if you take a look now at the updated FIDDLE
I added an empty span in between paragraphs to clear the float and also added a media query so it looks nicer on smaller screens
This was the simplest way I could come up with to solve your issue hope that helps!!
I am not sure about the the column issue. You should make a fiddle for it so that we can help you faster. As far as the first cap issue. This is pretty tricky, what are your constraints? Can you hardcode it look right or do you have to do it dynamically?
I have posted a hardcoded solution here. It is basically just using
:before
http://jsfiddle.net/emersive/bdAWQ/1/
I have Chenges below css
p { float:left;}
#multicolumn { line-height: 20px; } /*need for IE browser*/
Demos
Related
I like to know if is possible to specify the border drawing style (not border-style) with CSS (I need that works at least on webkit).
Well, I have an element like div.border and it have four-side border 5px silver solid. But depending of class addition, like div.border.red-mark, it will receive a border-left: 15px red solid. I need that the rendering style be rectangular and not adaptative to line width (or angled to a point).
To clarify, take a look at this example. And I need get something like that. But I can't modify the HTML structure, like I did on second example; I really can use only CSS for that.
Is it possible?
You could use CSS pseudo-content to achieve a fake border, like this:
.red-mark:before {
content: '';
display:block;
width: 15px;
position: absolute;
top: -15px;
left: -15px;
bottom: -15px;
background: red;
}
See: http://jsfiddle.net/MnPka/1/
The minus positions are because 0 starts within the border. You may be able to change this behaviour by setting box-sizing though support for that isn't that great yet - http://caniuse.com/#search=box-sizing
The :before solution offered by Josh Davenport is probably the best answer here, but just for completeness, I should also mention border-image.
border-image is a relatively new CSS feature that allows you to specify an image for each of the border edges and corners. This would enable you to design your border exactly as you want it.
Your example would be a pretty trivial case for it; as I said the other answer is probably better for you; but for more complex cases, it's a great little feature to have in your toolbox.
You can read more about it here at the MDN.
The one thing to note (as mentioned on the MDN link above) is browser compatibility. It will work in most current browsers, but not in any current IE versions (IE10 or earlier), and may have issues in older versions of other browsers. However, you specified you were particularly looking for a Webkit solution, and it has been supported in webkit browsers for ages, so it should be okay.
In IE10, a focused textbox containing a value will have a little x added to the right of them. This x allows a user to click on the textbox in order to clear its value.
Other questions have touched on removing this feature from the user's view, but I wanted to maintain the feature in addition to adding my own icon to the right of the textbox, such as a search icon. Unfortunately, those icons end up colliding, so I needed to determine a way to move the icon and my searches never turned up any results.
The question that I kept trying to answer: what other properties can be used with the IE10+ ::-ms-clear pseudo-element?
UPDATE: As the other answerer pointed out, the MS documentation has been updated as June 19, 2013 to include all of the properties available to ::-ms-clear. It's unclear if this applies to IE10 rather than the currently forthcoming IE11, so I will leave the rest of the answer below.
For completeness, they have also updated the documentation for ::-ms-reveal, which appears to be the exact same as ::-ms-clear.
The answer below at least applies to IE10.
I cannot find an exhaustive list, which lead me to experimentation:
::-ms-clear {
margin: *; /* except margin-left */
background: *;
color: *;
display: none|block;
visibility: *;
}
Unfortunately, I was not able to trick IE's developer mode (F12) into showing me the ::-ms-clear properties in the style tree, so I had to try things by hand and reload the page in order to experiment. I even tried cheating by adding onblur=this.focus(), but that did not work.
CSS properties that did something, and seemed useful:
margin: The margin gave me a way to shift it from the right side of the textbox. I shifted it by the size of my icons, plus 1-3 pixels to give a buffer. Only margin-left does not seem to work.
background: The background of just the x. Applying any background settings puts your desired content behind it; it does not replace the x!
color: Controls the color of the x.
display: As the question that got me here notes, none will hide the x.
visibility: Seems to work as one would expect similar to display.
You can combine the color and background to replace the x with a different background image so long as it fits within the given size of the x, which appears to be around 20px, but that is just me eyeballing it.
::-ms-clear {
color: transparent;
background: no-repeat url("../path/to/image") center;
}
CSS properties that did something, but did not seem useful:
padding: It affects the x, but never as I actually expected its effect (everything seemed to hide the icon, or at least shift it out of view).
position: Identical behavior as padding. Admittedly, I am much more of a programmer than a designer, so this may be my own shortcoming.
CSS properties that I guessed might do something, but that did nothing at all:
text-align
float
Adding other CSS pseudo-elements does not affect ::-ms-clear. Specifically, I tried ::after and ::before on it with content: "y", and neither one got a result.
Obviously it depends on the size of the companion icon that you intend to apply to the textbox, but I use 14-16px icons and I found that margin-right: 17px gave the x a clear gap, which shifts the x to the left of my right-aligned icon. Interestingly, margin-left seems to have no effect, but you can use a negative value for margin-right.
The actual CSS that I ended up using, which prevented my icon from being covered by the x.
[class^="tbc-icon-"]::-ms-clear, [class*=" tbc-icon-"]::-ms-clear {
margin-right: 17px;
}
My icons all share the same base name, tbc-icon-, which means that the ::-ms-clear pseudo-element is automatically applied to all of them whenever they are applied. In all other cases, the pseudo-element behaves in its default manner.
Of interest, ::-ms-reveal seems to behave the same way, and if you were going to apply icons to password fields (far less likely I expect), then you can follow the above example:
[class^="tbc-icon-"]::-ms-clear, [class*=" tbc-icon-"]::-ms-clear,
[class^="tbc-icon-"]::-ms-reveal, [class*=" tbc-icon-"]::-ms-reveal {
margin-right: 17px;
}
One list is available on MS site, at least.
http://msdn.microsoft.com/en-us/library/windows/apps/hh465740.aspx
(But maybe I misunderstood the question.)
It's better to see a bug for yourself in Firefox: http://jsfiddle.net/kizu/btdVd/
The picture, showing the bug:
And the bug filled in 2007 on bugzilla.
The bug appears when you're adding ::first-letter pseudo-element with display: inline-block, and then change the font-size of this first-letter.
More letters in a word after the first: more extra space added (or subtracted — if the font-size is lesser than block's).
Adding float: left to the first-letter inverts the bug: with bigger font-size the width of inline-block shrinks.
So, the question: is there any CSS-only workaround for this bug? It's somewhat killing me.
I've found that triggering reflow on the whole page (or any block with a problem) fixes the problem, so I've found a way to trigger it on every such block with one-time CSS animation: http://jsfiddle.net/kizu/btdVd/23/
Still, while this fix have no downsides in rendering, it have some other ones:
it would work only for Fx5+ (that supports animations);
it still flashes the original bug for a few ms, so it's maybe somewhat blinky.
So, it's not an ideal solution, but would somewhat help when Fx4- would be outdated. Of course, you can trigger such fix onload with JS, but it's not that nice.
I don't think there's a good solution.
I have come up with a flaky solution for you though:
.test:first-letter {
font-size: 2em;
letter-spacing: -0.225em;
}
Add the letter-spacing style to the :first-letter selector in your Fiddle, and you'll find the blocks go back to roughly the right size.
Explanation:
Basically, the bug is being caused by the whole block taking its size from the font specified in the first-letter.
What I'm doing here with the letter-spacing is trying to adjust the size of this font, without affecting it's physical appearance. Adjusting the letter spacing in this way in normal text would result in the letters overlapping each other by .225 of a character width on either side.
I was initially hoping that a value of -0.25 would be sufficient -- ie a quarter of a character on each side would reduce the width of each character by half, which would be what we want because the first letter is font-size:2em, so it's twice as big.
However, the calculation isn't quite as clean as that, because the first and last characters in the string would only be overlapped on one side each, and because the first letter does in fact want to be double width, even if the rest of the characters don't.
All of this means that the exact letter-spacing value required to counter-act the bug will vary depending on how long the text, as well as the font sizes of the original text and the first letter. This is why I had to experiment a bit with the value of the letter spacing to get it working, and also explains why I couldn't get quite a perfect fit on all the text rows in your Fiddle. I would have needed a slightly different value for each block.
The value of -0.225 seems to be about the closest I can get to it being right for all your examples, but in practice you'll need to adjust it to suit your site.
Don't forget also that this is a Firefox bug, and therefore you'll need to write it in as a browser-specific hack of some sort. And be careful to keep an eye on the Firefox bug report you linked; when it does get fixed, you'll need to work out a way to keep your hack in place for users of old versions, but remove it for users with the fix.
[EDIT]
The only other working solution I've come up with is simply not to use the features which trigger the bug. ie drop the :first-letter selector, and use a separate <span> for the first letter of your text if you want to style it differently.
This is the obvious answer really, and would of course solve the problem (and would also mean that your styled first letter works in older browsers), but it would not be ideal from a semantic perspective, and more importantly doesn't actually answer the question, which is why I didn't offer it as a solution in my original answer.
I have been trying to find alternative work around for the bug as well, but the options are limited, and nothing I've tried has given as good results as my initial suggestion.
I tried a hack of making the :first-letter invisible, and using :before to display the big leading capital letter. However, this didn't work for me. I didn't linger on it too long so you may be able to get it working, but there is a problem with it in that you'd have to define the leading letter in your CSS, which wouldn't be ideal.
Another possible solution is to use the CSS font-stretch: condensed; property on the :first-letter. This would reduce the width of the first letter back to 1em, and thus resolve the width issue of the rest of the text. The down sides of this, however, are that firstly it would make the leading letter look squashed, which is probably not what you want, and secondly this style only works for fonts which support the condensed property. It turns out that this isn't well supported by the standard fonts, so may not be workable for you.
In the end, the original letter-spacing solution is still the only way I've found to really work around the bug.
This bug still exists, but some of the fixes don't work anymore. Even after triggering a reflow with an animation, the inline-block returned to the same size for me. I couldn't use the letter-spacing trick because I am already using it on the first letter, that is what is causing the problem for me. I solved the problem by adding this to the CSS for the affected selector:
-moz-padding-end: *number of pixels to compensate*;
At the moment, moz-padding-end seems to be specific to Firefox, and it can add or remove width to the end of the inline-block. Because this is a Firefox specific bug, that did the trick for me.
I know this thread is quite old now, but apparently this bug has not been fixed yet.
Using animation does work but there is a noticeable FOUT (Flash Of Unstyled Text). I was able to work around the problem by wrapping the first-letter in a span. This does work around both the sizing issue and the FOUT, it does add extra elements to the markup, so it depends on the needs of your site/application if this is the best fit.
.test {
background: rgba(0,0,0,0.15); /* For visualisation */
display: inline-block;
}
.test:first-letter {
font-size: 2em;
}
.test2:first-letter {
float: left;
}
.test3:first-letter {
font-size: .5em;
}
<h1>Inline-block with bigger first-letter</h1>
<span class="test">Broken</span>
<br><br>
<span class="test"><span>F</span>ixed</span>
<h1>+ floating to first-letter</h1>
<span class="test test2">Broken</span>
<br><br>
<span class="test test2"><span>F</span>ixed</span>
<h1>small size for first-letter</h1>
<span class="test test3">Broken</span>
<br><br>
<span class="test test3"><span>F</span>ixed</span>
<h1>small size, floating first-letter</h1>
<span class="test test2 test3">Broken</span>
<br><br>
<span class="test test2 test3"><span>F</span>ixed</span>
As of 2023, this is still happening in Firefox.
This is my solution using SASS, but you can see how to make it bare CSS:
txt-brand {
display:inline-block;
}
///Firefox only ///
#-moz-document url-prefix() {
margin-right: .1em;
white-space: nowrap;
&::after {
content: '\00a0';
}
}
}
.txt-brand::first-letter {
letter-spacing: -.11em;
}
This hadn't hit me until now (and this is not only in webkit browsers). On all texts in like p tags, h1 tags etc... there's an extra space over and below the text.
In chrome I found this:
user agent stylesheet
-webkit-margin-before: 1em;
-webkit-margin-after: 1em;
-webkit-margin-start: 0px;
-webkit-margin-end: 0px;
This makes the alignment wrong in some places. And yes I'm using a reset stylesheet and no padding or margin are added. Pretty much a basic setup. Why is this and how do I solve it?
You can also directly modify those attributes like so:
-webkit-margin-before:0em;
-webkit-margin-after:0em;
Works for me in Chrome/Safari. Hope that helps!
These -webkit-margin(s) are overwritten by margin: 0; padding: 0;. Do not worry about them.
Extra space? Maybe you've set line-height:?
I had the same issue. Displaying correctly in Firefox but not Chrome.
I had a closer look at http://meyerweb.com/eric/tools/css/reset/ and found that I hadn't declared a general line-height for the body tag in my stylesheet. Set it to 1.2 and that recreated the correct layout in both browsers.
Just remove the whitespace between tags e.g.
<p id="one"></p>
<p id="two"></p>
becomes:
<p id="one"></p><p id="two"></p>
I had a same problem. Extra space between menu links. None of the above solutions worked. What worked for me, was negative margin.
Just do something like this:
margin: 0 -2px;
NEW EDIT:
This has nothing to do with -webkit-margins. Most likely your problem occurs with inline elements. This happens because you have spaces or line breaks between your inline elements. To fix this, you have many options:
remove all spaces and line-breaks between inline elements
skip element closing tag - for example </li> (HTML5 does not care)
negative margin (as stated above - problems with IE6/7 - who cares, upgrade ;)
set font-size: 0; to problematic inline element container (has issues with android and if font-sizing with ems)
give up inline and use float (this way you loose text-align:center)
Explained more specifically and examples by CHRIS COYIER
I was having this same problem with my <h3> tag. I tried setting margin:0;, but it didn't work.
I found that I was habitually commenting out lines in my css by using //. I never noticed it because it hadn't caused any problems before. But when I used // in the line before declaring <h3>, it caused the browser to skip the declaration completely. When I traded out // for /**/ I was able to adjust the margin.
Moral of this story: Always use proper commenting syntax!
For me, the picture was:
* {margin:0;padding:0;}
Firefox (FF) and Google Chrome both put 0.67em margins regardless.
FF showed its default margin, but crossed out, but applied it anyway.
GC showed its default margin (-webkit-margin-before...) uncrossed.
I applied
* {margin:0;padding:0; -webkit-margin-before: 0; -webkit-margin-after: 0;}
but to no avail, although GC now showed its default margin crossed.
I found out, that I can apply either
line-height: 0;
or
font-size: 0;
to achieve the desired effect.
This makes sense, if one assumes, that the margin is of the .67em - type.
If anybody could give an explanation, why browsers make our lives miserable by applying a line-height dependent, non-removable margin, i would be really grateful.
For me in Chrome it was some 40px padding-start that was causing this. I did the following that worked:
ul {
-webkit-padding-start: 0em;
}
-webkit-margin-before: 0em;
-webkit-padding-start: 0;
-webkit-margin-after: 0em;
This solved it for me when I was having this exact problem.
In your css file add the following.
* {
-webkit-margin-before: 0em !important;
-webkit-margin-after: 0em !important;
}
'*' selects all css elements and overrides the webkit-margin.
Modern properties
The following properties should be used instead.
margin-block-start: 0;
margin-block-end: 0;
It's very rare to need to use these at all, but the following can be useful to avoid extra space after the last paragraph in a series.
p:last-child
{
margin-block-end: 0;
}
I also found that even in Chrome you can trigger the 'ghost margin' by setting margin to inherit in some cases.
https://developer.mozilla.org/en-US/docs/Web/CSS/margin-block-start
I had the same problem. Suddenly one out of my three table cells containing data its header was moved down a little bit. My problem was simply solved by adding this:
table td
{
vertical-align: top;
}
Seems like some other element in a 'higher' style sheet was telling my data to center itself in the cell, instead of just staying on top.
I guess its just stupid, and wasnt really a problem... but the next person to read this topic might have the same stupid error as i did :)
Take care!
If user agent stylesheet is kicking in, it is because the tag property was not properly defined in your css stylesheet.
Chances are that a typo, forgotten bracket or semicolon is breaking up your stylesheet BEFORE reaching the tag property settings your page later refers to or "needs".
Run your CSS thru error checking, like CSS LINT and fix whichever errors are eventually detected.
While some people use this reset.
* {
margin: 0;
padding: 0;
}
Is every element has default margin and padding in each browser default stylesheet( but differently)?
While eric meyer collected some most used selectors and given this to all
{
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-size: 100%;
vertical-align: baseline;
background: transparent;
}
Are those elements has different type of font sizes?
different baseline, different background, outline and border?
if we keep besides cons of universal selector.
is this
* {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-size: 100%;
vertical-align: baseline;
background: transparent;
}
better than this
* {
margin: 0;
padding: 0;
}
You can find all default styles here: CSS2.1 User Agent Style Sheet Defaults.
If you investigate the list closely, then you'll notice that the browser-specific margins are only set for HTML-standard block elements and that nowhere a browser-specific padding is been set. In other words, the padding: 0 is superfluous. But indeed, the margin is the most disbalanced among browsers, to answer your actual question.
I am probably going to tread on someone's toes here, but in my humblest opinion using a CSS reset stylesheet is ridiculous. You would have to redefine most of those margins (and paddings) yourself anyway. You could as good just learn and keep yourself the rule to define yourself the margin (and if necessary padding) for every block element which you're going to use in the document.
As to the remnant of the reset:
The border: 0 is superflous as well. The <hr> and the most form input elements are the only elements which have a default border. Without it, the <hr> is invisible (actually, this fails in IE6/7) and the text input elements on a form with same background color are invisible as well.
The outline should certainly not be resetted, it breaks accessibility. You need to control it yourself, e.g. resetting it yourself on only links with a (background) image since that's the major reason to reset it. But still, it breaks accessibility. Rather consider giving it a different outline color or style so that it is still visible, but less disturbing.
The font-size: 100% would force you to redefine them yourself in the <h1>, <h2>, etc elements. But even without the reset, you would often already like to do that anyway. What's the point of this reset then?
The vertical-align: baseline; breaks alignment of <sub> and <sup> so that they look like <small>. Further the table headers may also be affected. Those defaults to middle in all browsers. You would need to redefine them yourself again. Plus, it is known that this reset may cause IE6/7 to go havoc with images.
The value of background: transparent; is unclear to me. I don't see any point of this reset expect that it may make IE6/7 mad. You would also need to redefine the background color for all form input elements yourself again which just adds more work (for the case they're placed in a colored container). I am sure that whenever you encounter an element which needs transparent background, you could easily spot that yourself and set it yourself.
Enfin, see what you do with this information. I don't stop you from using the CSS reset. I myself have found the CSS reset only useful >10 years back when I was just starting with HTML/CSS. But with years and years, I've learnt as well that this is plain nonsense. But I admit, it's useful for starters since the reset will force them to set the margins and other stuff themselves explicitly. Which you could do as good without the reset.
Well, 'better than this' is hard to say, but the one with more stuff does more.
outline 0 makes links not have the dotted border around them.
Border 0 makes images and such not have a border around them.
font-size: 100% probably does something like ensure the fonts are 100%.
vertical-align: baseline sets all vertical alignments to the bottom of the container,
background: transparent prevents some png problems.
but margin:0 and padding:0 are two that defiantly should not be omitted from your reset list.
The short answer is: Feel free to set all of those if you are ready to override it for any element that may need it later.
However, note that you may have a lot of work ahead of you when it comes to form elements. They require at least a border to look good, and some of them (e.g. buttons) need a padding too. Also, some browsers display a 3D-ish border around buttons by default. If you set border to 0, you will not be able to get that 3D look back using CSS.
Also, you might want to check out http://www.blueprintcss.org/. It equalises browsers quite well, it seems, though I haven't tried it myself.