Anthony Kong Anthony Kong - 2 months ago 24
CSS Question

Unable to hide flex items by changing width or flex-basis

I want to achieve this effect:

In the default state, there are four buttons. One of them is a 'Move' button.

Beginning

When a user clicks on it, I want to expand the button and show additional text and input.

End, expanded state

However I am unable to achieve the 'default state'. The 'To ' always appears. I have tried

flex-basis
and
width: 0px
but there is no effect, like so

not working

How can I hide a flex box element without using
display:none
. The main reason for not using
display
is because I want to expand the widget with some css animation on width.

Here is the HTML code:

<div class="multiselect-controls">
<span class="multiselect-controls-container medium-theme">
<button type="submit" class="btn btn-multi-select multi-edit">
<span class="multiselect-text">Edit</span>
</button>
<button type="submit" class="btn btn-multi-select multi-copy">
<span class="multiselect-text">Copy</span>
</button>
<button type="submit" class="btn btn-multi-select multi-move" onclick="expandMe();">
<span class="multiselect-text">Move</span>
<span class="multi-move-input">
to <input class="multi-move-to-target" type='text'></input>
</span>
</button>
<button type="submit" class="btn btn-multi-select multi-delete">Delete</button>
<span class='icon icon-cross close-multiselect-controls'></span>
</span>
</div>


and
css(less)
code:

btn-multi-select {
display:flex;
width: 100px;
}

.multi-move-input {
flex-basis: 0px;
// overflow: hidden;
flex-grow: 0;
flex-shrink: 1;
}

.expanded {
&.multi-move {
width: 150px;
}
.multi-move-input {
flex-grow: 1;
flex-basis: auto;
}
}

.multi-move-to-target {
width: 30px;
height: 20px;
color: black;
}


Javascript:

function expandMe(event) {
$('.multi-move').toggleClass('expanded');
}


The code is also available here: http://codepen.io/kongakong/pen/amdrJZ

Answer

How can I hide a flex box element without using display:none? The main reason for not using display is because I want to expand the widget with some css animation on width.

You can use max-width, which is a animatable property.

Start it at 0, then have it expand to some extra large number. The element will only expand enough to fit content.

.multi-move-input {
  display: inline-flex;
  max-width: 0;
  transition: .5s;
  overflow: hidden;
}

.expanded {
  &.multi-move { }
  .multi-move-input {
    max-width: 200px;
    transition: 1s;
  }
}

revised codepen

Two things to consider:

  1. I've only focused on the hide/show transition, which is your question. But note that the input is inside the button's clickable area. This means when you try to input data it will fire the transition and close the button.
  2. Button elements and flex containers may cause unexpected behavior in some browsers. See this post: Flexbox not working on <button> element in some browsers