9

背景

我有一个小的单级 CSS 弹出菜单(嗯,从技术上讲,它是一个扩展元素)。它绝对定位在一个相当窄的父绝对定位元素的左下角。请参阅下面的第二个h1元素:

<div id="controls">
   <h1>Controls 1</h1>
   <h1 id="size" class="poplinks button">
      Size
      <a href="#" class="button selected" title="small"><img src=""></a>
      <a href="#" class="button" title="medium"><img src=""></a>
      <a href="#" class="button" title="large"><img src=""></a>
   </h1>
</div>

这很简单地变成了一个扩展菜单/弹出窗口,如下所示:

.poplinks:hover {
   width:auto;
}
.poplinks a {
   display:none;
}
.poplinks:hover a {
   display:inline-block;
}

问题

这会产生以下类似按钮的元素:

按钮

h1样式width:48px;,并且还有一个样式规则可以在悬停时应用于width:auto;元素h1,所以它应该能够扩大。但是,在悬停时,当我希望它向右延伸时(超出父元素的包含框),子菜单被迫保持不超过父元素的宽度。

垂直的

我想看到的(通过将元素移到父级之外获得,但我希望它保留在内部以继承样式,因此当我将菜单栏从左侧移动到顶部时,它会自动跟随):

在此处输入图像描述

这可能吗?你有什么建议?

在 JS Fiddle中亲自体验一下。

浏览器

注意:我计划在 Firefox、Chrome 和 IE 8 中使用此功能。我在 Firefox 和 Chrome 中进行主要样式设置,当基本完成后,将添加条件 CSS 以使 IE 正常工作并尽可能接近。

基本原理

我绝对定位父菜单的原因是我正在构建一个类似应用程序的页面来显示图像。该页面将托管在父 Windows 应用程序中,不需要大量识别信息:仅用于显示所需的图像。我选择使菜单绝对定位,而不是使用 inline-block 或浮动或其他方法来使我的菜单列就位(有两个)。但是,它不必是这种方式。如果您对替代布局或策略有建议,我会全力以赴。

4

3 回答 3

19

首先,你的#controls需要overflow:visible。然后,#size应该给出明确left的而不是right. 最后,.poplinks需要white-space: nowrap防止换行。

http://jsfiddle.net/VaWeK/11/

于 2013-07-12T07:21:13.977 回答
4

我正在写这个答案,因为我将来可能会再次需要它。

尽管我在所选答案中找到了这一点,但它也提到了 OP 询问的许多其他细节,并且不知何故最终隐藏了解决我的问题的重要部分。

对我来说诀窍是:white-space: nowrap

我需要一个下拉组件,我认为这是一个常见的用例。

下面的代码使用Reactand styled-components

const styled = window.styled;

const LS = {};

LS.DropdownButton_DIV = styled.div`
  position: relative;
  width: 150px;
  height: 30px;
  display: flex;
  align-items: center;
  padding-left: 8px;
  border: 1px solid silver;
  user-select: none;
  cursor: pointer;
  margin-bottom: 100px;
`;

LS.Dropdown_DIV = styled.div`
  position: absolute;
  left: 0;
  top: 100%;
  display: ${props => props.open ? "block" : "none"};
`;

LS.DropdownItem_DIV = styled.div`
  display: flex;
  padding-left: 8px;
  border: 1px solid silver;
  /* THIS IS WHAT SOLVES THE PROBLEM */  
  white-space: ${props => props.noWrap ? "nowrap" : "initial"};
`;

function App() {

  const [open1,setOpen1] = React.useState(false);
  const [open2,setOpen2] = React.useState(false);

  function toggleDropdown1() {
    setOpen1((prevState) => !prevState);
  }
  
  function toggleDropdown2() {
    setOpen2((prevState) => !prevState);
  }

  return(
    <React.Fragment>
    
      <LS.DropdownButton_DIV onClick={toggleDropdown1}>
        Dropdown Button 1
        <LS.Dropdown_DIV open={open1}>
          <LS.DropdownItem_DIV>
            Dropdown Item Longer Than Parent
          </LS.DropdownItem_DIV>
        </LS.Dropdown_DIV>
      </LS.DropdownButton_DIV>
      
      <LS.DropdownButton_DIV onClick={toggleDropdown2}>
        Dropdown Button 2
        <LS.Dropdown_DIV open={open2}>
          <LS.DropdownItem_DIV noWrap={true}>
            Dropdown Item Longer Than Parent
          </LS.DropdownItem_DIV>
        </LS.Dropdown_DIV>
      </LS.DropdownButton_DIV>
      
    </React.Fragment>
  );
}

ReactDOM.render(<App/>, document.getElementById("root"));
* {
 box-sizing: border-box;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<script src="//unpkg.com/styled-components@4.0.1/dist/styled-components.min.js"></script>
<div id="root"/>

于 2020-04-24T15:11:39.147 回答
0

两种方法:你可以硬编码一个绝对定义的宽度,或者你可以做一个大于 100% 的相对宽度。100% 的宽度将是包含 div 的 100%(只要该 div 具有定义的宽度)。如果此 div 具有绝对宽度,这意味着它是用像素而不是百分比或ems 定义的,那么您可以简单地使悬停 css 比父 div 更宽。例如,如果您的父 div 宽度为 100 像素,则悬停在子元素上的宽度应为 200 像素或 200% 或类似的东西。

于 2013-07-12T01:19:33.530 回答