[html] Make button width fit to the text

While I was fiddling with this 'Fancy 3D Button' example, I found that the width seemed to be hard-coded to fit the text's width.

Here is the HTML / CSS:

_x000D_
_x000D_
body {_x000D_
  background-image: url(http://subtlepatterns.com/patterns/ricepaper.png)_x000D_
}_x000D_
a {_x000D_
  position: relative;_x000D_
  color: rgba(255, 255, 255, 1);_x000D_
  text-decoration: none;_x000D_
  background-color: rgba(219, 87, 5, 1);_x000D_
  font-family: 'Yanone Kaffeesatz';_x000D_
  font-weight: 700;_x000D_
  font-size: 3em;_x000D_
  display: block;_x000D_
  padding: 4px;_x000D_
  -webkit-border-radius: 8px;_x000D_
  -moz-border-radius: 8px;_x000D_
  border-radius: 8px;_x000D_
  -webkit-box-shadow: 0px 9px 0px rgba(219, 31, 5, 1), 0px 9px 25px rgba(0, 0, 0, .7);_x000D_
  -moz-box-shadow: 0px 9px 0px rgba(219, 31, 5, 1), 0px 9px 25px rgba(0, 0, 0, .7);_x000D_
  box-shadow: 0px 9px 0px rgba(219, 31, 5, 1), 0px 9px 25px rgba(0, 0, 0, .7);_x000D_
  margin: 100px auto;_x000D_
  width: 160px;_x000D_
  text-align: center;_x000D_
  -webkit-transition: all .1s ease;_x000D_
  -moz-transition: all .1s ease;_x000D_
  -ms-transition: all .1s ease;_x000D_
  -o-transition: all .1s ease;_x000D_
  transition: all .1s ease;_x000D_
}_x000D_
a:active {_x000D_
  -webkit-box-shadow: 0px 3px 0px rgba(219, 31, 5, 1), 0px 3px 6px rgba(0, 0, 0, .9);_x000D_
  -moz-box-shadow: 0px 3px 0px rgba(219, 31, 5, 1), 0px 3px 6px rgba(0, 0, 0, .9);_x000D_
  box-shadow: 0px 3px 0px rgba(219, 31, 5, 1), 0px 3px 6px rgba(0, 0, 0, .9);_x000D_
  position: relative;_x000D_
  top: 6px;_x000D_
}
_x000D_
<link href='http://fonts.googleapis.com/css?family=Yanone+Kaffeesatz:700' rel='stylesheet' type='text/css'>_x000D_
_x000D_
<a href="javascript:void(0);">Push me!</a>
_x000D_
_x000D_
_x000D_

Normal look

If I remove the width property, the button would fill the page width.

Without the width property

Is there any way to make the button's width fit to the text, automatically?

This question is related to html css

The answer is


just add display: inline-block; property and removed width.


If you are developing to a modern browser. https://caniuse.com/#search=fit%20content

You can use:

width: fit-content;

If you are aiming for maximum browser support, modern approach is to place button in a div with display:flex; and flex-direction:row; The same trick will work for height with flex-direction:column; or both height and width(will require 2 divs)


Pretty late and not sure if this was available when the question was asked, set width: auto;

Seems to do the trick


Keeping the element's size relative to its content can also be done with display: inline-flex and display: table

The centering can be done with..

  • text-align: center; on the parent (or above, it's inherited)

  • display: flex; and justify-content: center; on the parent

  • position: absolute; left: 50%; transform: translateX(-50%); on the element with position: relative; (at least) on the parent.

Here's a flexbox guide from CSS Tricks

Here's an article on centering from CSS Tricks.

Keeping an element only as wide as its content..

  • Can use display: table;

  • Or inline-anything including inline-flex as used in my snippet example below.

Keep in mind that when centering with flexbox's justify-content: center; when the text wraps the text will align left. So you will still need text-align: center; if your site is responsive and you expect lines to wrap.

_x000D_
_x000D_
body {_x000D_
  display: flex;_x000D_
  flex-direction: column;_x000D_
  height: 100vh;_x000D_
  padding: 20px;_x000D_
}_x000D_
.container {_x000D_
  display: flex;_x000D_
  justify-content: center; /* center horizontally */_x000D_
  align-items: center; /* center vertically */_x000D_
  height: 50%;_x000D_
}_x000D_
.container.c1 {_x000D_
  text-align: center; /* needed if the text wraps */_x000D_
  /* text-align is inherited, it can be put on the parent or the target element */_x000D_
}_x000D_
.container.c2 {_x000D_
 /* without text-align: center; */_x000D_
}_x000D_
.button {_x000D_
  padding: 5px 10px;_x000D_
  font-size: 30px;_x000D_
  text-decoration: none;_x000D_
  color: hsla(0, 0%, 90%, 1);_x000D_
  background: linear-gradient(hsla(21, 85%, 51%, 1), hsla(21, 85%, 61%, 1));_x000D_
  border-radius: 10px;_x000D_
  box-shadow: 2px 2px 15px -5px hsla(0, 0%, 0%, 1);_x000D_
}_x000D_
.button:hover {_x000D_
  background: linear-gradient(hsl(207.5, 84.8%, 51%), hsla(207, 84%, 62%, 1));_x000D_
  transition: all 0.2s linear;_x000D_
}_x000D_
.button.b1 {_x000D_
    display: inline-flex; /* element only as wide as content */_x000D_
}_x000D_
.button.b2 {_x000D_
    display: table; /* element only as wide as content */_x000D_
}
_x000D_
<div class="container c1">_x000D_
  <a class="button b1" href="https://stackoverflow.com/questions/27722872/">This Text Is Centered Before And After Wrap</a>_x000D_
</div>_x000D_
<div class="container c2">_x000D_
  <a class="button b2" href="https://stackoverflow.com/questions/27722872/">This Text Is Centered Only Before Wrap</a>_x000D_
</div>
_x000D_
_x000D_
_x000D_

Fiddle

https://jsfiddle.net/Hastig/02fbs3pv/


I like Roger Cruz's answer of:

width: fit-content;

and I just want to add that you can use

padding: 0px 10px;

to add a nice 10px padding on the right and left side of the text in the button. Otherwise the text would be right up along the edge of the button and that wouldn't look good.


Try to add display:inline; to the CSS property of a button.