Problem when trying to style buttons and anchors alike - html

The HTML page shown below has four "buttons". Two of them are real button tags, but two are actually anchors (I deliberately left the underlining in their style so you can tell them apart). The goal was to style them using a btn class in a way that they look the same and align next to each other in a "button bar". But when you load the page in a browser, you will notice two differences between the buttons and the anchors - the buttons have a vertical offset, and their content is centered vertically. However, they use the same style class, and even when I compared the computed styles with browser developer tools, I could find no difference.
So why does this happen? I already found that not setting overflow and the height and instead adjusting it via padding and font-size can be used as a workaround. So it seems to have something to do with setting the height. But why do you get such an effect when you set it? And changing the overflow property strangely reverses the offset effect. I considered it might have to do with the box-sizing property which seems to be different for anchors and buttons, and could cause the height to be interpreted differently - but since there are no paddings and margins, it should not make a difference, it would also not alter the offset, and setting the box-sizing property manually for the class did not change the effect either.
Again, I'm not primiarly looking for a fix here, much less a discussion whether it's a good idea to style buttons and anchors the same, but I'm interested in a solid explanation of this CSS phenomenon. Is it a browser quirk with styling buttons? But then why do all the browsers (Firefox, Chrome, IE) show the same effect? Or did I overlook something obvious?
<!DOCTYPE html>
<html><head>
<style>
.btn {
margin: 0;
padding: 0;
overflow: hidden;
border: none;
outline: none;
background-color: grey;
color: white;
height: 2em;
width: 10em;
font-size: 20px;
font-family: sans-serif;
display: inline-block;
text-align: center;
}
</style>
</head><body>
<button type="submit" class="btn">
Button
</button><a href="#" class="btn">
Button
</a><button type="button" class="btn">
Button
</button><a href="#" class="btn">
Button
</a>
</body></html>

Since a button that has not been styled looks different than an anchor that hasn't been styled, if you apply the same style to both, there will be a difference. I think the only solution is to just apply different classes to the buttons, and to the anchors.

Ok, I think I found the answer myself:
I noticed that after adding vertical-align: middle; and line-height: 2em; to the btn class, the links and anchors will look exactly the same. You can then also remove the overflow: hidden.
The default values for these properties are vertical-align: baseline; and line-height: normal; - when you add these properties, the differences are still visible.
So I guess the deeper reason for this puzzle is a flaw in my underlying assumption that if the computed style properties, as shown in the developer tools, are the same, then two elements should also look the same. However, obviously there are settings with values like vertical-align: baseline; and line-height: normal; which do not have unambiguous meanings, instead they can have different meanings for different kinds of tags: E.g., where the baseline is and what a "normal" line height is, is defined differently for button and anchor tags.

Related

In CSS, how can I reset a button's default browser-given styles?

i suspect there's a problem with the way browsers are applying default styles onto things like <button> elements
to fully understand my conundrum, this involves the shadow dom, and i'll explain that at the end, however for now, let's just focus on a version of the problem i have isolated to a simple question about CSS:
how can i reset a <button> to it's original browser default styling?
i've tried setting properties like border: initial;, and border: unset; and border: inherit;, but in every case, setting any of these css properties on a button element causes the browser to release any of its default styling
please see the following example on codepen
<button>control</button>
<button id="b1">b1</button>
<button id="b2">b2</button>
<button id="b3">b3</button>
<button id="b4">b4</button>
<button id="b5">b5</button>
<button id="b6">b6</button>
<style>
#b1 { background: initial; }
#b2 { background: unset; }
#b3 { background: inherit; }
#b4 { border: initial; }
#b5 { border: unset; }
#b6 { border: inherit; }
</style>
in this example, the first button is a control, so we can see the default browser styling
on the buttons where we try to reset background, the button totally changes style, the background disappears, and even the border changes
on the buttons where we try to reset border, the button totally changes, but oddly in a different way -- here the border disappears, and the background changes
what explains these strange and unexpected results?
why do i need to reset a button, you ask? that seems like a weird thing to do, you think? consider my use case involving web component and the shadow dom:
i'm using the shadow dom with some web components
i want to allow users to OPTIONALLY set styles on some shadow <button>s
so i set button { border: var(--button-border); }
however even when the user doesn't supply --button-border, the button is visually manged and browser styles are not applied
even setting button { border: var(--button-border, initial); } and the other examples don't work
how can i give the users of my components a hook to style the buttons away from the default, however leaving intact the default buttons when they decide not to apply any button styles?
i feel like i'm stuck in a pickle here, and the browser might not have an answer to this problem — i fear that i'll have to either abandon the default styling for buttons within my components (bad practice, the default buttons are meant to be familiar to users), otherwise abandon any custom styling to the buttons (bad for designers that's for sure) — is there any hope to salvage this situation?
Try:
button {
background: none;
border: none;
padding: 0;
}

How do I fix a cut-off checkbox element in Firefox?

I'm on FF 43.0.3, Mac OS 10.9.3. FF is cutting of the native checkbox on the right. It's not a css problem on my part; I confirmed the cutting off in CodePen. I also viewed a couple of random sites with checkmarks, and I see the same. I made sure to reset my browser zoom to default, and the default font is Times at 16px. I also tried turning off hardware acceleration via Preferences as another site suggested. Didn't work. The only code I have in my CodePen example is <input type="checkbox">
Would love to hear any suggestions.
This happens because of styling issues, and appears differently on different browsers. So try fixing the styling of the checkbox element and it's parent element, add some or all of these styles:
#parent-element { /*Or Whatever The ID Of The Parent Element Is*/
line-height: 20px;
height: 20px;
display: block
}
#checkbox-element { /*Or Whatever The ID Of The Checkbox Element Is*/
display: block;
height: 20px
}
Try changing the styles of the elements with different values to suit your needs.

What makes <button> to position inner text in the center(vertically&horizontally)?

I'm trying to understand what makes <button> tag to position text right in the center of the element by default. Horizontal alignment is controlled by the text-align: center. What controls the vertical alignment?
Here is the fiddle to play with: http://jsfiddle.net/GW9KL/
Here is Chrome default stylesheets for <button>. Can't see what makes it vertically aligned.
This question intrigued me so I began to investigate. To cut a long story short, in chrome at least, display: -webkit-box; is applied to button elements. I had to install a developer plugin to see it. i have copy and pasted the styling and applied it to a div. A JSfiddle shows the results
Example http://jsfiddle.net/GW9KL/2/
div {
text-align: center;
color: buttontext;
border: 2px outset buttonface;
background-color: buttonface;
font: -webkit-small-control;
-webkit-appearance: button;
display: -webkit-box;
-webkit-box-pack: center;
-webkit-box-align: center;
}
Unfortunately, there is no CSS property that defines the vertical alignment of <button> text and it is handled differently depending on the browser it's viewed in. Most solutions involve line-height or padding fixes for quick and dirty, but ultimately it seems best to go with alternatives such as using styled <div> elements.
This post was helpful for me about button text: Position of text in a submit button
Here is the W3C spec on the vertial-align property, which points out that it applies to "inline-level and 'table-cell' elements": http://www.w3.org/TR/CSS2/visudet.html
If you're looking for how browsers decide where the text lies, then the comments on this are correct. It's up to the browser and it's going to be hidden in the code and unmanipulable.

How to make buttons look same as other elements and vice-versa

While assembling a site, I discovered that it's quite complicated to get buttons work with other elements, so that all elements look all the same.
That happens for example in a menu, where some buttons are real buttons, while other are just HTML links to other pages. Other example may be a form, where buttons are expected to be as large as other inputs.
Please see my jsFiddle to understand what I'm talking about. In the example, I want button to look like other elements!
Some code since SO requests it:
HTML:
Both elements shole be of the same size
<div id="menulike">
<button>DO SOMETHING</button>
GO TO SOMETHING
</div>
CSS:
div#menulike button, div#menulike a {
/*reset some default styles*/
border-style: none;
border-width: 0px;
text-decoration: none;
/*Inline or inline-block*/
display: inline;
display: inline-block;
/*colors and stuff*/
color: white;
font-weight: bold;
background: black;
/*This is important - size is expected to be the same*/
padding: 3px;
margin: 1px;
width: 220px;
font-size: 12pt;
text-align: center;
}
Why does this happen?
The reason your elements do not look the same when applying the same styling is due to default styling applied on elements. This is due to the elements being different. The differences may also be different depending on the browser.
How do you fix this?
You simply need to override all the properties that are different between elements. A lot of the differences between browsers can be solved with CSS resets.
Why isn't my example working?
Regarding your particular issue, the button has different width because you are not overriding all of the button's CSS properties. Try adding the following to your text inputs:
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
This should give them all the same width. Alternatively, you can give your button box-sizing: content-box, which is the default for most elements.
As for the difference between the button and link, all I can see is the cursor icon when you hover over them. This can be changed with the cursor property:
cursor: default;
Edit:
I just noticed the second example has different heights for the button and link in Firefox (I was using Chrome before, which didn't show it). I believe this is combination of both height and box-sizing. Setting both to the same value for the elements should give them the same size.
I'm only guessing, but I think the reason height is needed in this case is because the font is treated differently between buttons and links in FF. Since no height was set, the fonts took up different amounts of space in the two elements, even if it was the same font with same font size.
I'm not sure, but the form elements (buttons, select, radio buttons) are provided by the browser. Each browser/OS have an way to show it. So I think you need to write a separated css block for it.

Display Table Cell inconsistency.

Hey I was wondering why this happens:
http://jsfiddle.net/dSVGF/
The buttons do not fill the container yet the
anchors do. What is fundamentally different
between the two tags stylistically?
<div class="table">
A
B
C
</div>
<div class="table">
<button href="#">A</button>
<button href="#">B</button>
<button href="#">C</button>
</div>
.table {
display: table;
width: 100%;
outline: 1px solid red;
}
.table > * {
display: table-cell;
outline: 1px solid lightgreen;
}
I suppose that the fundamental difference between these elements is that <button> is treated as replaced element (at least by some browsers), and is rendered with the help of non-CSS browser built-in mechanisms. There are several issues in Bugzilla about the rendering limitations of buttons caused by this (e.g. https://bugzilla.mozilla.org/show_bug.cgi?id=733914).
IE9+ and Opera seem not to treat <button> as a replaced element, which seems more correct according to the latest HTML spec, but is still rather unclear in CSS.
Whether or not a button tag actually accepts "display: table-cell" is dependent on the browser, apparently. I ran a quick check in Chrome developer tools: In the calculated styles, the display on the buttons was set to inline-block. When I tried the same in IE10, it accepted the change and the buttons actually sized as table cells.
A button is a clickable element which allows you put anything within such as text, image etc.
An anchor tag is specific for Hyperlinks.
Source: w3schools.com