버튼 또는 필드 셋 요소에서 작동하지 않는 Flex / Grid 레이아웃


91

나는- <button>태그 의 내부 요소 를 flexbox의 justify-content: center. 그러나 Safari는 그들을 중심에 두지 않습니다. 다른 태그에 동일한 스타일을 적용 할 수 있으며 의도 한대로 작동합니다 ( <p>-tag 참조 ). 버튼 만 왼쪽 정렬됩니다.

Firefox 또는 Chrome을 사용하면 차이를 확인할 수 있습니다.

덮어 써야하는 사용자 에이전트 스타일이 있습니까? 아니면이 문제에 대한 다른 해결책이 있습니까?

div {
  display: flex;
  flex-direction: column;
  width: 100%;
}
button, p {
  display: flex;
  flex-direction: row;
  justify-content: center;
}
<div>
  <button>
    <span>Test</span>
    <span>Test</span>
  </button>
  <p>
    <span>Test</span>
    <span>Test</span>
  </p>
</div>

그리고 jsfiddle : http://jsfiddle.net/z3sfwtn2/2/


답변:


132

문제

일부 브라우저에서 <button>요소는 및 display사이의 전환을 넘어서 값 변경을 허용하지 않습니다 . 즉, 요소는 플렉스 또는 그리드 컨테이너 또는 .blockinline-block<button><table>

뿐만 아니라 <button>요소,이 제약 조건에 적용 찾을 수 있습니다 <fieldset><legend>뿐만 아니라, 요소.

자세한 내용은 아래 버그 보고서를 참조하세요.

참고 : 플렉스 컨테이너는 될 수 없지만 <button>요소는 플렉스 항목이 될 수 있습니다.


해결책

이 문제에 대한 간단하고 쉬운 브라우저 간 해결 방법이 있습니다.

의 내용 감싸 buttonA의를 span하고 확인 span플렉스 컨테이너를.

조정 된 HTML (에서 래핑 된 button콘텐츠 span)

<div>
    <button>
        <span><!-- using a div also works but is not valid HTML -->
            <span>Test</span>
            <span>Test</span>
        </span>
    </button>
    <p>
        <span>Test</span>
        <span>Test</span>
    </p>
</div>

조정 된 CSS (타겟팅 됨 span)

button > span, p {
    display: flex;
    flex-direction: row;
    justify-content: center;
}

수정 된 데모


참조 / 버그 보고서

<button>Flexbox는 내용을 차단하지만 가변 서식 컨텍스트를 설정하지 않습니다.

사용자 (오리올 Brufau) 의 아이들이 <button>blockified되어, 지시로 인 flexbox 사양. 그러나 <button>플렉스 대신 블록 서식 컨텍스트를 설정하는 것 같습니다.

사용자 (Daniel Holbert) : 이것이 HTML 사양에 필요한 것입니다. 여러 HTML 컨테이너 요소는 "특별"하며 displayGecko 의 CSS 값을 효과적으로 무시합니다. [인라인 수준인지 블록 수준인지는 제외]. <button>이 중 하나입니다. <fieldset>& <legend>도 있습니다.

<button>요소 내부에 display : flex / grid 및 columnset 레이아웃 지원 추가

사용자 (Daniel Holbert) :

<button>순수한 CSS에서는 (브라우저로) 구현할 수 없으므로 CSS의 관점에서 보면 약간의 블랙 박스입니다. 이것은 그들이 예를 들어 의지와 같은 방식으로 반드시 반응하지 않는다는 것을 의미합니다 <div> .

이것은 flexbox에만 국한된 것이 아닙니다. 예를 들어 overflow:scroll버튼 을 놓으면 스크롤바를 렌더링하지 않으며 , 버튼을 놓으면 테이블로 렌더링하지 않습니다 display:table.

한 걸음 더 뒤로 물러 나면 <button>. <fieldset>그리고 <table>특별한 렌더링 동작이있는 것을 고려하십시오 .

추천하고 오래된 timey HTML 요소 <button><table>그리고 <fieldset>단순히 사용자 정의 지원하지 않는 display요소 주위에 다른 콘텐츠를 흐르는 값의 매우 높은 수준의 질문에 대답의 목적 이외의 "이 요소 블록 레벨 또는 인라인 수준이다", .

참조 :


3
나는 왜 그것이 <button>s에서 작동하지 않을 수 있는지 알지만 왜 도대체에서도 작동하지 <fieldset>않습니까? 이 요소는 플렉스 컨테이너에 유효한 일반 블록 수준 요소로 간주되어야하지 않습니까?
fritzmg

3
@fritzmg. 동의합니다. 규칙은 아마도 Flex 및 Grid와 같은 CSS3 기술이 이미 존재하므로 재평가되어야합니다.
Michael Benjamin

따라서 우리는 버튼이 오용되는 것을 방지하고 싶지만 다른 것을 오용하여 버튼 안에 넣을 수 있습니다. 웹의 나머지 부분과 같은 논리처럼
Romain Vincent

1
@Michael_B 주장을하는 실제 텍스트에 대한 참조를 추가하는 것을 고려하십시오. 내 의견에 답장 할 필요가 없습니다. 주장하는 텍스트에 추가하면 찬성표를드립니다.
mikemaccana

2
A div는 a의 자식이 될 수 없습니다 button. 구식 HTML에서 생각하면 블록 수준 요소는 인라인 수준 요소의 자식이 될 수 없기 때문입니다. 하지만 오늘, HTML5로, 기술적으로 정답이다 요소는 받아 들일 수 어법 내용을 . A 는 구문 내용 을 나타내지 만 a 는 그렇지 않습니다. A 는 흐름 콘텐츠를 나타냅니다 . 자세한 내용buttonspandivdiv
마이클 벤자민


1

Chrome 83을 시작하면 button이제으로 작동 inline-grid/grid/inline-flex/flex합니다. 여기 에서이 새로운 기능에 대한 자세한 내용을 볼 수 있습니다.

다음은 스 니펫입니다 (Chrome 83 이상을 사용하는 경우)

button {
  display: inline-flex;
  height: 2rem;
  align-items: flex-end;
  width: 4rem;
  -webkit-appearance: none;
  justify-content: flex-end;
}
<!-- 

The align-items keyword should fail in Chrome 81 or earlier, but work in Chrome 83 or later. To see the error, the button needs styles that make it more of an extrinsic container. In other words, it needs a height or width set. 
 
-->
<button>Hi</button>
<input type="button" value="Hi">

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.