CSS:具有max-height的容器,之后,子div应该开始滚动

时间:2016-09-10 10:24:29

标签: html css html5 css3 flexbox

我有一个尽可能小的模态窗口,延伸到高度的70%。之后,模态的内容(但不是模态本身)应该开始滚动。我无法做到这一点。

我的HTML看起来像这样:

<div class="dialog"> 
    <div class="ui-root" >
        <div class="title" />
        <div class="body" />
        <div class="buttons" />
    </section>
</div>

这是CSS的想法:

 .dialog { max-height: 70% }
 .ui-root { display: flex }
 .body { flex: 1; overflow: scroll }

用语言说:

  • 如果身体内容很小,.body的高度可以是内容高度。
  • 如果身体内容很大,那么.body开始弯曲直到它超出.dialog的最大高度。现在它开始滚动。

问题:

  • 忽略max-height值。

玩它:

http://jsfiddle.net/ch7n6/904/

3 个答案:

答案 0 :(得分:2)

预计此处会忽略max-height,因为它已应用于dialog,并且不会影响其子元素flexbox(应具有特定高度)

  

如果未指定flexbox的高度,则您无法胜任   将其包含在父元素中。

当我向max-height: 100% flexbox ui-root提供html, body { height: 100%; } .dialog { max-height: 50%; width: 40%; height: 50%; } .dialog.underflowing-dialog { position: absolute; } .dialog.overflowing-dialog { position: absolute; left: 50%; } .ui-root { display: flex; flex-direction: column; background-color: red; max-height: 100%; } .ui-root article { flex: 1; overflow: scroll; } .underflowing-dialog .height-setting-content { height: 9px; } .overflowing-dialog .height-setting-content { height: 9999px; } .ui-root header { background-color: gray; } .ui-root footer { background-color: gray; }时,了解它是如何解决的:

&#13;
&#13;
<div class="dialog overflowing-dialog"> 
    <section class="ui-root" >
        <header class="title" >Should always be visible</header>
        <article class="body">  
          this should scroll
          <div class="height-setting-content"></div>
          and have the minimum height
        </article>
        <footer class="buttons" >Should always be visible</footer>
    </section>
</div>

<div class="dialog underflowing-dialog">
    <section class="ui-root" >
        <header class="title" >Should always be visible</header>
        <article class="body">  
          this should scroll
          <div class="height-setting-content"></div>
          and have the minimum height
        </article>
        <footer class="buttons" >Should always be visible</footer>
    </section>
</div>
&#13;
#include "stdafx.h"
#include <iostream>

#include <windows.h>
#include <dshow.h>

#pragma comment(lib, "strmiids")

HRESULT EnumerateDevices(REFGUID category, IEnumMoniker **ppEnum)
{
    // Create the System Device Enumerator.
    ICreateDevEnum *pDevEnum;
    HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
        CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDevEnum));

    if (SUCCEEDED(hr))
    {
        // Create an enumerator for the category.
        hr = pDevEnum->CreateClassEnumerator(category, ppEnum, 0);
        if (hr == S_FALSE)
        {
            hr = VFW_E_NOT_FOUND;  // The category is empty. Treat as an error.
        }
        pDevEnum->Release();
    }
    return hr;
}

HRESULT InitCaptureGraphBuilder(
    IGraphBuilder **ppGraph,  // Receives the pointer.
    ICaptureGraphBuilder2 **ppBuild  // Receives the pointer.
)
{
    if (!ppGraph || !ppBuild)
    {
        return E_POINTER;
    }
    IGraphBuilder *pGraph = NULL;
    ICaptureGraphBuilder2 *pBuild = NULL;

    // Create the Capture Graph Builder.
    HRESULT hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,
        CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**)&pBuild);
    if (SUCCEEDED(hr))
    {
        // Create the Filter Graph Manager.
        hr = CoCreateInstance(CLSID_FilterGraph, 0, CLSCTX_INPROC_SERVER,
            IID_IGraphBuilder, (void**)&pGraph);
        if (SUCCEEDED(hr))
        {
            // Initialize the Capture Graph Builder.
            pBuild->SetFiltergraph(pGraph);

            // Return both interface pointers to the caller.
            *ppBuild = pBuild;
            *ppGraph = pGraph; // The caller must release both interfaces.
            return S_OK;
        }
        else
        {
            pBuild->Release();
        }
    }
    return hr; // Failed
}

void DisplayDeviceInformation(IEnumMoniker *pEnum)
{
    IMoniker *pMoniker = NULL;

    while (pEnum->Next(1, &pMoniker, NULL) == S_OK)
    {
        IPropertyBag *pPropBag;
        HRESULT hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
        if (FAILED(hr))
        {
            pMoniker->Release();
            continue;
        }

        VARIANT var;
        VariantInit(&var);

        hr = pPropBag->Read(L"DevicePath", &var, 0);
        if (SUCCEEDED(hr))
        {
            // The device path is not intended for display.
            printf("Device path: %S\n", var.bstrVal);
            VariantClear(&var);
        }

        IGraphBuilder *ppGraph;
        ICaptureGraphBuilder2 *pBuild; // Capture Graph Builder
        hr = InitCaptureGraphBuilder(&ppGraph, &pBuild);


        IBaseFilter *pCap; // Video capture filter.
        hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pCap);
        if (SUCCEEDED(hr))
        {
            hr = ppGraph->AddFilter(pCap, L"Capture Filter");
            if (SUCCEEDED(hr)) {
                IBaseFilter *pMux;
                hr = pBuild->SetOutputFileName(
                    &MEDIASUBTYPE_Avi,  // Specifies AVI for the target file.
                    L"C:\\a\\Example.avi", // File name.
                    &pMux,              // Receives a pointer to the mux.
                    NULL);              // (Optional) Receives a pointer to the file sink.

                hr = pBuild->RenderStream(
                    &PIN_CATEGORY_CAPTURE, // Pin category.
                    &MEDIATYPE_Video,      // Media type.
                    pCap,                  // Capture filter.
                    NULL,                  // Intermediate filter (optional).
                    pMux);                 // Mux or file sink filter.

                                           // Release the mux filter.
                pMux->Release();

                IConfigAviMux *pConfigMux = NULL;
                hr = pMux->QueryInterface(IID_IConfigAviMux, (void**)&pConfigMux);
                if (SUCCEEDED(hr))
                {
                    pConfigMux->SetMasterStream(0);
                    pConfigMux->Release();
                }

                IConfigInterleaving *pInterleave = NULL;
                hr = pMux->QueryInterface(IID_IConfigInterleaving, (void**)&pInterleave);
                if (SUCCEEDED(hr))
                {
                    pInterleave->put_Mode(INTERLEAVE_CAPTURE);
                    pInterleave->Release();
                }

            }
        }

        pPropBag->Release();
        pMoniker->Release();
    }
}

int _tmain(int argc, _TCHAR* argv[])
{

    HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
    if (SUCCEEDED(hr))
    {
        IEnumMoniker *pEnum;

        hr = EnumerateDevices(CLSID_VideoInputDeviceCategory, &pEnum);
        if (SUCCEEDED(hr))
        {
            DisplayDeviceInformation(pEnum);
            pEnum->Release();
        }
        CoUninitialize();
    }

    int i;
    std::cin >> i;
    return 0;
}
&#13;
&#13;
&#13;

答案 1 :(得分:0)

你走了。诀窍是只能让你的内容滚动。

&#13;
&#13;
.ui-root {
  width: 40%;
}

.ui-root header,
.ui-root footer {
  background-color: gray;
  float: left;
  width: 100%;
}

.scroll {
  width: 100%;
  float: left;
  background-color: red;
  min-height: 50px;
  max-height: 50vh;
  overflow-y: auto;
}

@keyframes scaling {
  from {
    height: 20px;
  }
  to {
    height: 999px;
  }
}

.content {
  width: 100%;
  -webkit-animation: scaling 5s linear infinite;
  -moz-animation: scaling 5s linear infinite;
  -ms-animation: scaling 5s linear infinite;
  -o-animation: scaling 5s linear infinite;
  animation: scaling 5s linear infinite;
  background: lightgray;
}
&#13;
<section class="ui-root">
  <header class="title">Should always be visible</header>
  <div class="scroll">
    <article class="content">
      this should scroll
    </article>
  </div>
  <footer class="buttons">Should always be visible</footer>
</section>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

我最终为自己解决这个问题的方法是在我的对话框中强制执行对flexbox的严格和特殊使用。

事实证明,如果<dialog>max-heightdisplay: flex,且子元素也是display: flex,那么高度计算的工作方式与预期完全一样。