在 CSS3 或 jQuery 中,将元素的宽度从 0 调整到 100%,使其及其包装器的宽度达到所需的宽度,无需预设宽度

发布于 2024-12-11 22:21:54 字数 1518 浏览 0 评论 0原文

http://jsfiddle.net/nicktheandroid/tVHYg/

悬停时 .wrapper,它的子元素 .contents 应该从 0px 动画到它的自然宽度。然后,当鼠标从 .wrapper 中移除时,它应该以动画方式返回到 0px.wrapper 元素的宽度应仅达到所需的宽度(允许 .contents 增长),因此 .wrapper 的宽度应增长并像 .contents 那样缩小宽度。 .contents 不应设置宽度。我正在使用 CSS3,但它可以在 jQuery 中完成,那就没问题了。

问题: 看到 JSfiddle

  1. .wrapper 不仅有它需要的宽度。
  2. .contents 增长时,当它几乎达到全宽时,它会跳到下一行当
  3. 悬停在 .wrapper.contents 上时当它应该动画到 0px 时消失

.wrapper {
    display: inline-block;

    height: 20px;
    width: auto;
  
    padding:10px;
  
    background:#DDD;
}

.contents {
    display:inline-block;
  
    width:0%;
  
    white-space:nowrap;
    overflow:hidden;
  
    background:#c3c;
}

.wrapper:hover .contents {
    -webkit-transition: width 1s ease-in-out;
    -moz-transition: width 1s ease-in-out;
    -o-transition: width 1s ease-in-out;
    transition: width 1s ease-in-out;

    width:100%;
}
<div class="wrapper">
    <span>+</span>
    <div class="contents">These are the contents of this div</div>
</div>

http://jsfiddle.net/nicktheandroid/tVHYg/

When hovering .wrapper, it's child element .contents should animate from 0px to it's natural width. Then when the mouse is removed from .wrapper, it should animate back down to 0px. The .wrapper element should only be as wide as it needs to be (allowing .contents to grow), so .wrapper should grow in width and shrink in width as .contents does. There should be no set width for .contents. I'm using CSS3, but it could be accomplished in jQuery, that would be fine.

The problem:
See the JSfiddle

  1. .wrapper is not only as wide as it needs to be.
  2. when .contents grows, when it's almost at it's full width, it jumps down to the next line
  3. When hovering off of .wrapper, .contents vanishes, when it should animate down to 0px

.wrapper {
    display: inline-block;

    height: 20px;
    width: auto;
  
    padding:10px;
  
    background:#DDD;
}

.contents {
    display:inline-block;
  
    width:0%;
  
    white-space:nowrap;
    overflow:hidden;
  
    background:#c3c;
}

.wrapper:hover .contents {
    -webkit-transition: width 1s ease-in-out;
    -moz-transition: width 1s ease-in-out;
    -o-transition: width 1s ease-in-out;
    transition: width 1s ease-in-out;

    width:100%;
}
<div class="wrapper">
    <span>+</span>
    <div class="contents">These are the contents of this div</div>
</div>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

生生不灭 2024-12-18 22:21:54

我想我已经明白了。

.wrapper {
    background:#DDD;
    display:inline-block;
    padding: 10px;
    height: 20px;
    width:auto;
}

.label {
    display: inline-block;
    width: 1em;
}

.contents, .contents .inner {
    display:inline-block;
}

.contents {
    white-space:nowrap;
    margin-left: -1em;
    padding-left: 1em;
}

.contents .inner {
    background:#c3c;
    width:0%;
    overflow:hidden;
    -webkit-transition: width 1s ease-in-out;
    -moz-transition: width 1s ease-in-out;
    -o-transition: width 1s ease-in-out;
    transition: width 1s ease-in-out;
}



.wrapper:hover .contents .inner {
   
    width:100%;
}
<div class="wrapper">
    <span class="label">+</span>
    <div class="contents">
        <div class="inner">
            These are the contents of this div
        </div>
    </div>
</div>

动画设置为 100% 会导致其换行,因为该框大于可用宽度(100% 减去 + 及其后面的空格)。

相反,您可以为内部元素设置动画,其 100%.contents 的总宽度。

I think I've got it.

.wrapper {
    background:#DDD;
    display:inline-block;
    padding: 10px;
    height: 20px;
    width:auto;
}

.label {
    display: inline-block;
    width: 1em;
}

.contents, .contents .inner {
    display:inline-block;
}

.contents {
    white-space:nowrap;
    margin-left: -1em;
    padding-left: 1em;
}

.contents .inner {
    background:#c3c;
    width:0%;
    overflow:hidden;
    -webkit-transition: width 1s ease-in-out;
    -moz-transition: width 1s ease-in-out;
    -o-transition: width 1s ease-in-out;
    transition: width 1s ease-in-out;
}



.wrapper:hover .contents .inner {
   
    width:100%;
}
<div class="wrapper">
    <span class="label">+</span>
    <div class="contents">
        <div class="inner">
            These are the contents of this div
        </div>
    </div>
</div>

Animating to 100% causes it to wrap because the box is bigger than the available width (100% minus the + and the whitespace following it).

Instead, you can animate an inner element, whose 100% is the total width of .contents.

鸠书 2024-12-18 22:21:54

http://jsfiddle.net/tVHYg/5/

.wrapper {
    background:#DDD;
    padding:1%;
    display:inline;
    height:20px;
}


span {
    width: 1%;
}

.contents {
    background:#c3c;
    overflow:hidden;
    white-space:nowrap;
    display:inline-block;
    width:0%;
}



.wrapper:hover .contents {
    -webkit-transition: width 1s ease-in-out;
    -moz-transition: width 1s ease-in-out;
    -o-transition: width 1s ease-in-out;
    transition: width 1s ease-in-out;

    width:90%;
}

http://jsfiddle.net/tVHYg/5/

.wrapper {
    background:#DDD;
    padding:1%;
    display:inline;
    height:20px;
}


span {
    width: 1%;
}

.contents {
    background:#c3c;
    overflow:hidden;
    white-space:nowrap;
    display:inline-block;
    width:0%;
}



.wrapper:hover .contents {
    -webkit-transition: width 1s ease-in-out;
    -moz-transition: width 1s ease-in-out;
    -o-transition: width 1s ease-in-out;
    transition: width 1s ease-in-out;

    width:90%;
}
败给现实 2024-12-18 22:21:54

一个较晚的答案,但我认为这个按照问题中的要求工作:)

这个使用 z-index 和绝对位置,并避免容器元素宽度在过渡中不增长的问题。

您可以调整文本的边距和填充以满足您的需要,并且如果需要,“+”可以更改为字体很棒的图标。

body {
  font-size: 16px;
}

.container {
  height: 2.5rem;
  position: relative;
  width: auto;
  display: inline-flex;
  align-items: center;
}

.add {
  font-size: 1.5rem;
  color: #fff;
  cursor: pointer;
  font-size: 1.5rem;
  background: #2794A5;
  border-radius: 20px;
  height: 100%;
  width: 2.5rem;
  display: flex;
  justify-content: center;
  align-items: center;
  position: absolute;
  z-index: 2;
}

.text {
  white-space: nowrap;
  position: relative;
  z-index: 1;
  height: 100%;
  width: 0;
  color: #fff;
  overflow: hidden;
  transition: 0.3s all ease;
  background: #2794A5;
  height: 100%;
  display: flex;
  align-items: center;
  border-top-right-radius: 20px;
  border-bottom-right-radius: 20px;
  margin-left: 20px;
  padding-left: 20px;
  cursor: pointer;
}

.container:hover .text {
  width: 100%;
  padding-right: 20px;
}
<div class="container">
  <span class="add">+</span>
  <span class="text">Add new client</span>
</div>

a late answer, but I think this one works as required in the question :)

this one uses z-index and position absolute, and avoid the issue that the container element width doesn't grow in transition.

You can tweak the text's margin and padding to suit your needs, and "+" can be changed to font awesome icons if needed.

body {
  font-size: 16px;
}

.container {
  height: 2.5rem;
  position: relative;
  width: auto;
  display: inline-flex;
  align-items: center;
}

.add {
  font-size: 1.5rem;
  color: #fff;
  cursor: pointer;
  font-size: 1.5rem;
  background: #2794A5;
  border-radius: 20px;
  height: 100%;
  width: 2.5rem;
  display: flex;
  justify-content: center;
  align-items: center;
  position: absolute;
  z-index: 2;
}

.text {
  white-space: nowrap;
  position: relative;
  z-index: 1;
  height: 100%;
  width: 0;
  color: #fff;
  overflow: hidden;
  transition: 0.3s all ease;
  background: #2794A5;
  height: 100%;
  display: flex;
  align-items: center;
  border-top-right-radius: 20px;
  border-bottom-right-radius: 20px;
  margin-left: 20px;
  padding-left: 20px;
  cursor: pointer;
}

.container:hover .text {
  width: 100%;
  padding-right: 20px;
}
<div class="container">
  <span class="add">+</span>
  <span class="text">Add new client</span>
</div>

暗恋未遂 2024-12-18 22:21:54

通过转换填充和宽度让它工作。

JSFiddle: http://jsfiddle.net/tuybk748/1/

<div class='label gray'>+
</div><!-- must be connected to prevent gap --><div class='contents-wrapper'>
    <div class="gray contents">These are the contents of this div</div>
</div>
.gray {
    background: #ddd;
}
.contents-wrapper, .label, .contents {
    display: inline-block;
}
.label, .contents {
    overflow: hidden; /* must be on both divs to prevent dropdown behavior */
    height: 20px;
}
.label {
    padding: 10px 10px 15px;
}
.contents {
    padding: 10px 0px 15px; /* no left-right padding at beginning */
    white-space: nowrap; /* keeps text all on same line */
    width: 0%;
    -webkit-transition: width 1s ease-in-out, padding-left 1s ease-in-out, 
        padding-right 1s ease-in-out;
    -moz-transition: width 1s ease-in-out, padding-left 1s ease-in-out, 
        padding-right 1s ease-in-out;
    -o-transition: width 1s ease-in-out, padding-left 1s ease-in-out, 
        padding-right 1s ease-in-out;
    transition: width 1s ease-in-out, padding-left 1s ease-in-out, 
        padding-right 1s ease-in-out;
}
.label:hover + .contents-wrapper .contents {
    width: 100%;
    padding-left: 10px;
    padding-right: 10px;
}

Got it to work by transitioning the padding as well as the width.

JSFiddle: http://jsfiddle.net/tuybk748/1/

<div class='label gray'>+
</div><!-- must be connected to prevent gap --><div class='contents-wrapper'>
    <div class="gray contents">These are the contents of this div</div>
</div>
.gray {
    background: #ddd;
}
.contents-wrapper, .label, .contents {
    display: inline-block;
}
.label, .contents {
    overflow: hidden; /* must be on both divs to prevent dropdown behavior */
    height: 20px;
}
.label {
    padding: 10px 10px 15px;
}
.contents {
    padding: 10px 0px 15px; /* no left-right padding at beginning */
    white-space: nowrap; /* keeps text all on same line */
    width: 0%;
    -webkit-transition: width 1s ease-in-out, padding-left 1s ease-in-out, 
        padding-right 1s ease-in-out;
    -moz-transition: width 1s ease-in-out, padding-left 1s ease-in-out, 
        padding-right 1s ease-in-out;
    -o-transition: width 1s ease-in-out, padding-left 1s ease-in-out, 
        padding-right 1s ease-in-out;
    transition: width 1s ease-in-out, padding-left 1s ease-in-out, 
        padding-right 1s ease-in-out;
}
.label:hover + .contents-wrapper .contents {
    width: 100%;
    padding-left: 10px;
    padding-right: 10px;
}
我还不会笑 2024-12-18 22:21:54

请检查以下代码片段

 /* DEBUG */
.lwb-col {
    transition: box-shadow 0.5s ease;
}
.lwb-col:hover{
    box-shadow: 0 15px 30px -4px rgba(136, 155, 166, 0.4);
 
}


.lwb-col--link {
    font-weight: 500;
  position: relative;
  display: inline-block;
}
.lwb-col--link::after{
    border-bottom: 2px solid;
    bottom: -3px;
    content: "";
    display: block;
    left: 0;
    position: absolute;
    width: 100%;
    color: #E5E9EC;

}
.lwb-col--link::before{
    border-bottom: 2px solid;
    bottom: -3px;
    content: "";
    display: block;
    left: 0;
    position: absolute;
    width: 100%;
    color: #57B0FB;
    transform: scaleX(0);
    

}
.lwb-col:hover .lwb-col--link::before {
    border-color: #57B0FB;
    display: block;
    z-index: 2;
    transition: transform 0.3s;
    transform: scaleX(1);
    transform-origin: left center;
}
<div class="lwb-col">
  <h2>Webdesign</h2>
  <p>Steigern Sie Ihre Bekanntheit im Web mit individuellem & professionellem Webdesign. Organisierte Codestruktur, sowie perfekte SEO Optimierung und jahrelange Erfahrung sprechen für uns.</p>
<span class="lwb-col--link">Mehr erfahren</span>
</div>

Please check following snippet

 /* DEBUG */
.lwb-col {
    transition: box-shadow 0.5s ease;
}
.lwb-col:hover{
    box-shadow: 0 15px 30px -4px rgba(136, 155, 166, 0.4);
 
}


.lwb-col--link {
    font-weight: 500;
  position: relative;
  display: inline-block;
}
.lwb-col--link::after{
    border-bottom: 2px solid;
    bottom: -3px;
    content: "";
    display: block;
    left: 0;
    position: absolute;
    width: 100%;
    color: #E5E9EC;

}
.lwb-col--link::before{
    border-bottom: 2px solid;
    bottom: -3px;
    content: "";
    display: block;
    left: 0;
    position: absolute;
    width: 100%;
    color: #57B0FB;
    transform: scaleX(0);
    

}
.lwb-col:hover .lwb-col--link::before {
    border-color: #57B0FB;
    display: block;
    z-index: 2;
    transition: transform 0.3s;
    transform: scaleX(1);
    transform-origin: left center;
}
<div class="lwb-col">
  <h2>Webdesign</h2>
  <p>Steigern Sie Ihre Bekanntheit im Web mit individuellem & professionellem Webdesign. Organisierte Codestruktur, sowie perfekte SEO Optimierung und jahrelange Erfahrung sprechen für uns.</p>
<span class="lwb-col--link">Mehr erfahren</span>
</div>

小嗷兮 2024-12-18 22:21:54

这还不是一个得到广泛支持的解决方案,但希望将其留在这里供未来的读者使用。

目前(截至 2024 年 11 月 11 日)calc-size 尚未真正得到支持。但是,一旦浏览器开始实现它并且不需要旧版浏览器支持,它就可以用于设置宽度和高度的动画。引用链接文档:

calc-size() CSS 函数允许您对固有大小值(例如 auto、fit-content 和 max-content)执行计算 [...]

calc-size() 返回值也可以进行插值,从而可以在动画和过渡中使用 size 关键字值。

在 MDN 文档中,还有一个 示例 使用 calc-size 函数进行基于高度的过渡。例如,您可以使用最新的 Chrome 对其进行测试。

This is not a widely supported solution yet, but wanted to leave it here for future readers.

Currently (as of 2024-11-11) the calc-size is not really supported yet. However, as soon as the browsers start to implement it and no legacy browser support is needed, it can be used to animate both width and height. Quote from the linked docs:

The calc-size() CSS function allows you to perform calculations on intrinsic size values such as auto, fit-content, and max-content [...]

calc-size() return values can also be interpolated, enabling size keyword values to be used in animations and transitions.

In the MDN docs, there is also an example for height-based transition using the calc-size function. You can test it with a recent Chrome, for example.

看轻我的陪伴 2024-12-18 22:21:54

我无法在不指定宽度的情况下使其工作,但以下 css 工作了

.wrapper {
    background: #DDD;
    padding: 10px;
    display: inline-block;
    height: 20px;
    width: auto;
}

.contents {
    background: #c3c;
    overflow: hidden;
    white-space: nowrap;
    display: inline-block;
    visibility: hidden;
    width: 1px;
    -webkit-transition: width 1s ease-in-out, visibility 1s linear;
    -moz-transition: width 1s ease-in-out, visibility 1s linear;
    -o-transition: width 1s ease-in-out, visibility 1s linear;
    transition: width 1s ease-in-out, visibility 1s linear;
}

.wrapper:hover .contents {
    width: 200px;
    visibility: visible;
}

我'我不确定您是否能够在不设置宽度的情况下使其正常工作。

I haven't been able to get it to work without specifying a width but the following css worked

.wrapper {
    background: #DDD;
    padding: 10px;
    display: inline-block;
    height: 20px;
    width: auto;
}

.contents {
    background: #c3c;
    overflow: hidden;
    white-space: nowrap;
    display: inline-block;
    visibility: hidden;
    width: 1px;
    -webkit-transition: width 1s ease-in-out, visibility 1s linear;
    -moz-transition: width 1s ease-in-out, visibility 1s linear;
    -o-transition: width 1s ease-in-out, visibility 1s linear;
    transition: width 1s ease-in-out, visibility 1s linear;
}

.wrapper:hover .contents {
    width: 200px;
    visibility: visible;
}

I'm not sure you will be able to get it working without setting a width on it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文