Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make flex container take width of content, not width 100%

Tags:

In the below example, I have a button with the following styles...

.button-flexbox-approach {
    /* other button styles */
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 1.5rem 2rem;
}

http://codepen.io/3stacks/pen/JWErZJ

But it automatically scales to 100% instead of the width of the content. You can set an explicit width, but then that doesn't allow your text to wrap naturally.

How can I make a button that has the inner text centered with flexbox, but doesn't grow to fit the size of the container?

.container {
  width: 100%;
  height: 100%;
}

.button {
/*   Simply flexing the button makes it grow to the size of the container... How do we make it only the size of the content inside it? */
  display: flex;
  justify-content: center;
  align-items: center;
  -webkit-appearance: none;
  border-radius: 0;
  border-style: solid;
  border-width: 0;
  cursor: pointer;
  font-weight: normal;
  line-height: normal;
  margin: 0;
  position: relative;
  text-align: center;
  text-decoration: none;
  padding: 1rem 2rem 1.0625rem 2rem;
  font-size: 1rem;
  background-color: #D60C8B;
  border-color: #ab0a6f;
  color: #fff;
}

.one {
  margin-bottom: 1rem;
}

.two {
/* You can put an explicit width on that, but then you lose the flexibility with the content inside */
  width: 250px;
}
<div class="container">
  <p>
    Button one is flexed with no width and it grows to the size of its container
  </p>
  <p>
    <a class="button one" href="#">Button</a>
  </p>
  <p>
    Button two is flexed with an explicit width which makes it smaller, but we have no flexibility for changing the content
  </p>
  <p>
    <a class="button two" href="#">Button 2</a>
  </p>
</div>
like image 540
3stacks Avatar asked Mar 09 '17 04:03

3stacks


People also ask

How do you give something a different width to flex?

A flexbox item can be set to a fixed width by setting 3 CSS properties — flex-basis, flex-grow & flex-shrink. flex-basis : This property specifies the initial length of the flex item. flex-grow : This property specifies how much the flex item will grow relative to the rest of the flex items.

How can you cause a flex item to grow in size?

flex: 1 0 200px; If you have one element that has a flex-basis of 200px, flex-grow of 1, and flex-shrink of 0, this element will be at minimum 200px wide, but it will be allowed to grow if there is extra space. In this case, you can think of the flex-basis as being a minimum width.

How to make flex items take the content width instead of width?

You can make flex items take the content width instead of the width of the parent container with CSS properties. The problem is that a flex container’s initial setting is align-items: stretch; meaning that items expand to cover the container’s full length along the cross axis.

How do I make a flex container more flexible?

The flex container becomes flexible by setting the display property to flex: The flex-direction property defines in which direction the container wants to stack the flex items. The column value stacks the flex items vertically (from top to bottom):

How to make a flex container responsive with CSS?

With a single line of CSS. we can make this responsive. By adding this line of code to the items in the flex container, we tell the flex items in each row to grow in width to fill up the remaining space. However, a problem occurs when there is an uneven amount of items per row:

How to align flex items to the center of the container?

The justify-content property is used to align the flex items: The center value aligns the flex items at the center of the container: The flex-start value aligns the flex items at the beginning of the container (this is default):


2 Answers

Instead of display: flex on the container, use display: inline-flex.

This switches the container from block-level (which takes the full width of its parent) to inline-level (which takes the width of its content).

This sizing behavior is similar to display: block vs. display: inline-block.

For a related problem and solution see:

  • Make flex items take content width, not width of parent container
like image 194
Michael Benjamin Avatar answered Oct 14 '22 02:10

Michael Benjamin


EDIT: Michael_B pointed out in his answer that inline-flex on the parent is the correct property for this use-case. I've updated my blog post accordingly.

It's not ideal, but if you wrap the button in a container that is inline-block, the button will scale naturally with the content, like so:

.button {
  /* other button styles */
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 1.5rem 2rem;
}
<div style="display: inline-block;">
  <a class="button">Button</a>
</div>

You can then set the max-width on the container and the text will wrap to multiple lines, but retain the correct vertical centering.

like image 40
3stacks Avatar answered Oct 14 '22 03:10

3stacks