Center one char in a rounded button element cross browser - html

I have a button with just one character which I would like to have exactly in the middle of the button
<button>+</button>
I have the following css:
button {
border: 2px solid lightgrey;
border-radius: 20px;
background-color: #fff;
outline: none;
height: 40px;
width: 40px;
font-size: 30px;
font-weight: 700;
line-height: 30px;
color: grey;
cursor: pointer;
user-select: none;
display: inline-flex;
align-items: center;
justify-content: center;
text-align: center;
}
JSFIDDLE
I probably have to many css properties in here but I have tried many different solutions. I've tested this button on chrome, safari and iPad:
None of them seem to be exactly at the center of the button. How can I do this cross browser ?
UPDATE: Even with the suggestions given below, I still see differences in different browsers. It is still hard to pixel-perfect center the chars. The solution I switched to is to use a svg for the chars, which solves this problem.

Here, try this CSS only plus button. I prefer using SVGs for icons, but you can use this ccs only button too :)
Markup
<button class="plus-button plus-button--small"></button>
<button class="plus-button"></button>
<button class="plus-button plus-button--large"></button>
SCSS
.plus-button {
border: 2px solid lightgrey;
background-color: #fff;
font-size: 16px;
height: 2.5em;
width: 2.5em;
border-radius: 999px;
position: relative;
&:after,
&:before {
content: "";
display: block;
background-color: grey;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
&:before {
height: 1em;
width: 0.2em;
}
&:after {
height: 0.2em;
width: 1em;
}
}
.plus-button--small {
font-size: 12px;
}
.plus-button--large {
font-size: 22px;
}
https://jsfiddle.net/robi_osahan/gwgL7Loj/

You could try with these CSS:
button {
border: 2px solid lightgrey;
border-radius: 20px;
background-color: #fff;
outline: none;
height: 40px;
width: 40px;
cursor: pointer;
user-select: none;
position: relative;
}
span {
color: grey;
font-size: 30px;
font-weight: 700;
display: inline-block;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
Here's a jsfiddle: https://jsfiddle.net/e490xzpy/5/

button {
border: 2px solid lightgrey;
border-radius: 50%;
background-color: #fff;
outline: none;
height: 40px;
width: 40px;
font-size: 30px;
font-weight: 700;
line-height: 10px;
color: grey;
cursor: pointer;
user-select: none;
text-align: center;
display:block;
}
And the fiddler link is
https://jsfiddle.net/3gfkpm0h/1/

I didn't fork your code, in fact I was coding something similar myself. I'm sharing my experience with you about absolutely centering (or middling or whatever) the icon inside a button.
If you are using line-height and border at the same time, you should subtract the total width of the border (sum of top and bottom border-width),
Absolute centering may not always be satisfying with every font-face you use with the buttons. The centering may look a bit off due to that font's baseline.
So, here is my take. Two techniques that I often use for these kinds of things:
Subtract the border-width from the line-height and stay happy with it.
Bring it one step further by adding an extra element within the relatively positioned button, and absolutely middle it using CSS transforms!
Here are some examples for you to test it yourself.
.btn {
position: relative;
display: inline-block;
vertical-align: bottom;
border: 2px solid;
width: 40px;
height: 40px;
line-height: 36px;
/* line-height = (height) - (border-top-width) + (border-bottom-width); */
background-color: #fff;
border-radius: 50%;
font-weight: 700;
font-size: 30px;
}
.btn-icon {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
line-height: 1;
}
<h3>Button without extra-element</h3>
<button class="btn">+</button>
<button class="btn">X</button>
<button class="btn">x</button>
<h3>Button with extra-element (.btn-icon)</h3>
<button class="btn"><span class="btn-icon">+</span></button>
<button class="btn"><span class="btn-icon">X</span></button>
<button class="btn"><span class="btn-icon">x</span></button>
See yourself what suits best for you. Hope it helped. Cheers!

Related

Only shrink flexbox horizontally

I've been trying to make a custom share button (for google classroom), and it seemed a flexbox was the best way to center the text. I'm making a share button, so I have an image and text. This is my current code for it:
a {
border-color: green;
border-style: solid;
color: white;
border-radius: 3px;
text-decoration: none;
background-color: green;
font-family: calibri;
display: flex-shrink;
justify-content: center;
align-items: center;
}
img {
padding: 5px;
height: 32px;
}
span {
padding: 5px;
}
<a href="https://classroom.google.com/share?url=http://example.com">
<img src="https://ktibow.github.io/classroom-logo.png"\>
<span>Share to Classroom</span>
</a>
It's supposed to make a nice rounded button, with the Google Classroom logo on the left and the text on the right. But instead, the background of the button shrinks down past the image.
I've tried using it without flex-shrink. Then it fills the whole page, which isn't how share buttons usually are, even though it does cover the background of the image. I've also tried setting the height of the span and the font size too. The height doesn't do anything, and if I do font size, then it gets cut off. I've tried flex-shrink: 0 too on the image. Does anybody know how to solve this?
New Design
I work with give the a tag display: inline-block
And move the img to position: absolute
I think it's look better now
a {
text-decoration: none;
display: inline-block;
margin: 10px 5px 10px 24px;
position: relative;
}
img {
position: absolute;
border-radius: 50%;
height: 38px;
top: -10px;
left: -18px;
}
span {
padding: 3px 5px 3px 24px;
background-color: green;
border-radius: 3px;
color: white;
font-family: calibri;
}
<a href="https://classroom.google.com/share?url=http://example.com">
<img src="https://ktibow.github.io/classroom-logo.png"\>
<span>Share to Classroom</span>
</a>
Or as ppl wrote with display: inline-flex
a {
text-decoration: none;
display: inline-flex;
align-items: center;
margin: 10px 5px 10px 24px;
background-color: green;
border-radius: 3px;
padding: 5px;
}
img {
height: 38px;
}
span {
padding: 5px;
color: white;
font-family: calibri;
}
<a href="https://classroom.google.com/share?url=http://example.com">
<img src="https://ktibow.github.io/classroom-logo.png"\>
<span>Share to Classroom</span>
</a>
a {
border-color: green;
border-style: solid;
color: white;
border-radius: 15px;
text-decoration: none;
background-color: green;
font-family: calibri;
display: flex-shrink;
justify-content: center align-items: center;
position: absolute;
display: flex;
}
img {
padding: 10px;
height: 30px;
}
span {
margin-top: 15px;
}
I don't know if this is what you are trying to achieve.
not the best way though

Create Button with toggle and text with a single element

I'm trying to create a button out of a single html element. The button needs to have a toggle slider and the text needs to be aligned vertically and horizontally. So I thought I can make use of :before element to help me make that happen. Here is what I have tried:
div {
width: 140px;
height: 40px;
background-color: #B3B3B3;
color: #FFF;
float: left;
clear: both;
border-radius: 5px;
font-size: 12px;
}
div:before {
content: '';
display: block;
width: 20px;
height: 36px;
background-color: #4D4D4D;
position: relative;
left: 2px;
top: 2px;
float: left;
border-radius: 5px;
}
<div>Text Value</div>
I have 2 problems with the above code:
I can't position the text how I want and I have tried using text-align and position to move it around.
I am using a float, which means that it will affect behavior of other elements around it, and I really don't want that.
Is what I want possible with a single element?
Here is the JS Fiddle: https://jsfiddle.net/m3q5Lcjy/
EDIT: The centered text should not be centered on the whole element, but on the light gray area.
This is how I would do this:
Array.from(document.querySelectorAll('.toggler')).forEach((item) => {
item.addEventListener('click', e => {
item.classList.toggle('active');
})
});
.toggler {
display: flex;
align-items: center;
justify-content: center;
position: relative;
box-sizing: border-box;
padding-left: 24px;
width: 140px;
min-height: 40px;
background-color: #B3B3B3;
color: #FFF;
border-radius: 5px;
font-size: 12px;
text-align: center;
cursor: pointer;
transition: padding .25s ease;
}
.toggler.active {
padding: 0 24px 0 0;
}
.toggler:before {
content: '';
display: block;
width: 20px;
background-color: #4D4D4D;
position: absolute;
bottom: 2px;
left: 2px;
top: 2px;
border-radius: 5px;
/* transition to make it look smoother */
transition: left .4s ease;
z-index: 1;
}
.toggler.active:before {
left: calc(100% - 22px);
}
<div class="toggler">Text Value</div>
<hr />
<div class="toggler active">Text Value realllllyy long</div>
<hr />
<div class="toggler">Text Value really far too long for this tiny, tiny, ohhh so tiny button. I recommend using shorter text though, but it won't break not even if you have like 10 or more lines.</div>
If anything about this implementation is unclear, feel free to ask.
Use flexbox to center your text vertically and horizontally. Then use absolute positioning on your pseudo element. Make sure parent element has relative positioning applied so absolute positioned pseudo stays within the parent.
div {
display: flex;
align-items: center;
justify-content: center;
position: relative;
box-sizing: border-box;
padding-left: 24px; /* 20px for :before width, 4px for :before offset */
width: 140px;
height: 40px;
background-color: #B3B3B3;
color: #FFF;
border-radius: 5px;
font-size: 12px;
}
div:before {
content: '';
display: block;
width: 20px;
height: 36px;
background-color: #4D4D4D;
position: absolute;
left: 2px;
top: 2px;
border-radius: 5px;
}
<div>Text Value</div>
You could place the text in a paragraph.
<div class="thediv">
<p class="theText">
enter text here
</p>
</div>
.thediv{
Your own style.
}
.theText{
position: absolute;
transform: translate(-50%, -50%);
top: 50%;
left: 50%;
}
I don't see why you would want it be in one element.
If you do want that, you should give the div a padding.
div{
background-color: #B3B3B3;
color: #FFF;
float: left;
border-radius: 5px;
font-size: 12px;
padding: 20px 70px;
}

How to position an absolute label, underneath a button and centered in the div

I'm trying to achieve this layout:
I have this:
<div class="button-wrapper">
<button>
<i></i>
</button>
<label>Carregamento Telemóvel</label>
</div>
My label has to be absolute positioned because it can't take space in the div. The div has to be the width of the button.
Any ideas?
EDIT: Sorry guys, my question was done in a little bit of hurry, so it was incomplete. I will now explain detailed.
I need all the div's to be responsive and don't have a fixed width.
The button itself it's contained in a row with others button's with the same layout.
The button's have to have the same margin between them, that's why I can't have the label with with because the length of the text it's never the same so the div's will have different sizes, and then I can't give the same margin between them.
Solution:
http://plnkr.co/edit/NYOb3uQnYrNFkfO6RaIG?p=preview
The plunker just works in -webkit- but it's all I need.
The trick to centering the label is a CSS3 transform
.button-wrapper label {
position: absolute;
top:100%;
left: 50%;
transform:translateX(-50%);
color: orange;
font-weight: bold;
}
body {
text-align: center;
}
.button-wrapper {
display: inline-block;
margin: 1em;
position: relative;
}
.button-wrapper i {
font-size: 72px;
background: orange;
line-height: 1.4em;
width: 1.4em;
border-radius:50%;
display: block;
}
.button-wrapper label {
position: absolute;
top:100%;
left: 50%;
transform:translateX(-50%);
color: orange;
font-weight: bold;
}
<div class="button-wrapper">
<i>K</i>
<label>Carregamento Telemóvel</label>
</div>
.button-wrapper {
display: inline-block;
max-width: 80px;
text-align: center;
}
.button-wrapper > button {
border-radius: 50%;
height: 40px; width: 40px;
background-color: orange;
position: relative;
border: 0 none;
display: inline-block;
}
.button-wrapper > button > i {
display: block;
height: 10px;
width: 10px;
background-color: #ffffff;
margin-top: -5px;
margin-left: -5px;
left: 50%;
top: 50%;
position: absolute;
}
.button-wrapper > label {
display: block;
font-size: 11px;
color: orange;
}
<div class="button-wrapper">
<button>
<i></i>
</button>
<label>Carregamento Telemóvel</label>
</div>
Without seeing your code, it's difficult to help you. But you can center an absolute positioned block element by combining margin:0 auto; left:0; right:0;
JSFiddle - http://jsfiddle.net/vfs3n68e/
Here's a very simple way to do it that I've created quickly: https://jsfiddle.net/rn8ysg5q/
HTML:
<div class="button-wrapper">
<button>
<i></i>
</button>
<br />
<label>Carregamento Telemóvel</label>
</div>
CSS:
.button-wrapper
{
/*border: 1px dotted red;*/
color: orange;
width: 100px;
position: relative;
text-align: center;
}
/* Reset button layout */
.button-wrapper button
{
background: none;
border: 0;
color: inherit;
/* cursor: default; */
font: inherit;
line-height: normal;
overflow: visible;
padding: 0;
-webkit-appearance: button; /* for input */
-webkit-user-select: none; /* for button */
-moz-user-select: none;
-ms-user-select: none;
}
.button-wrapper button
{
width: 60px;
height: 60px;
background-color: orange;
border-radius: 50%;
}
If that's what you're looking for I'll update it once I'm home in an hour and make some improvements.

Radial navigation: enlarge the space between the list elements

i'm working on this element http://zag-test.nowcommu.myhostpoint.ch/
what i need is to "enalrge" the entire element in the same position, but via CSS i can on enlarge the central button (CLICK button).
How can i solve?
CSS
.cn-button {
position: absolute;
top: 100%;
left: 50%;
z-index: 11;
margin-top: -2.25em;
margin-left: -3.78em;
padding-top: 0em;
width: 7.5em;
height: 7.5em;
border: none;
border-radius: 50%;
background: none;
background-color: #000;
color: #f9d70a;
text-align: center;
font-weight: 700;
font-size: 1.3em;
text-transform: uppercase;
cursor: pointer;
-webkit-backface-visibility: hidden;
You can use the transform attribute with scale to make everything bigger:
#cn-wrapper {
transform: scale(1.4) !important;
}
This is for the outer menu options, and the !important forces it to be used

How can I float dynamic div's next to each other?

I'm creating my own version of Twitter Bootstrap radio buttons purely based on CSS. The visual feedback for selected radio button is based on input[type="radio"]:checked + span.
As the content of my "buttons" can vary, the width is dynamic. This causes problem aligning the button next to each other.
In my JSfiddle I've set fixed width of 50px. Removing this and the buttons are on top of each other.
Can anyone point me in the right direction of how I can accomplish this?
Here is my code:
//HTML
<div class="button-group binary" data-toggle="buttons-radio">
<div class="radio-wrapper">
<input type="radio" class="active" name="status" value="1" />
<span class="background">Yes</span>
</div>
<div class="radio-wrapper">
<input type="radio" class="inactive" name="status" value="0" checked="checked" />
<span class="background">No</span>
</div>
</div>
//CSS
.button-group{
/*display: table;*/
display: block;
}
.radio-wrapper {
/*display: table-cell; */
display: inline-block;
position: relative;
height: 28px;
margin: 0;
width: 50px; /* I want this to be dynamic */
}
.radio-wrapper:first-child .background{
border-right: 0;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
}
.radio-wrapper:last-child .background{
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
}
input[type="radio"]{
position: absolute;
display: block;
height: 28px;
width: 100%;
z-index: 200;
cursor: pointer;
opacity: 0;
}
input[type="radio"]:checked + span {
background-color: #63B1DE;
color: #fff;
}
.background {
position: absolute;
z-index: 100;
height: 100%;
padding: 0 5px;
border: solid 1px #87A2B2;
background-color: #fff;
text-align: center;
line-height: 28px;
text-transform: uppercase;
}
If you remove position: absolute from you background class, you will no longer need the width style:
jsFiddle
.button-group{
/*display: table;*/
display: block;
}
.radio-wrapper {
/*display: table-cell; */
display: inline-block;
position: relative;
height: 28px;
margin: 0;
/*width: 50px; not needed*/
}
.radio-wrapper:first-child .background{
border-right: 0;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
}
.radio-wrapper:last-child .background{
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
}
input[type="radio"]{
position: absolute;
display: block;
height: 28px;
width: 100%;
z-index: 200;
cursor: pointer;
opacity: 0;
}
input[type="radio"]:checked + span {
background-color: #63B1DE;
color: #fff;
}
.background {
z-index: 100;
height: 100%;
padding: 0 5px;
border: solid 1px #87A2B2;
background-color: #fff;
text-align: center;
line-height: 28px;
text-transform: uppercase;
}
Having a look at your CSS, I think the issue you are having is because you are making the .background position: absolute it is not taking up any space in its parent, so the parent doesn't really have any width, this is why you have to manually set it. Stripping out the absolute positioning for the .background and actually making it an element that takes up space will give the parent a width (which will be based on its content). Now as far as correcting the on top of each other issue, I would think some floating here would work. CSS is here (I also removed some unnecessary rules)
.radio-wrapper {
position: relative;
float:left;
}
.radio-wrapper:first-child .background{
border-right: 0;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
}
.radio-wrapper:last-child .background{
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
}
input[type="radio"]{
position: absolute;
display: block;
height: 28px;
width: 100%;
z-index: 200;
cursor: pointer;
opacity: 0;
}
input[type="radio"]:checked + span {
background-color: #63B1DE;
color: #fff;
}
.background {
height: 100%;
padding: .5em;
border: solid 1px #87A2B2;
background-color: #fff;
text-align: center;
line-height: 28px;
text-transform: uppercase;
}
As per example fiddle.
I did add a bit more padding that you had though so please feel free to adjust as required. I also like padding in ems so if your font changes in size the padding is always relative.