공부

FlexLayout ) justifyContent / alignItems / alignSelf / alignContent 차이

Zedd0202 2022. 5. 25. 22:38
반응형

 

안녕하세요 :) Zedd입니다.

FlexLayout쓸 때 마다 헷갈리는 친구들이 있는데... 오늘 진짜 내 자신에게 너무 현타가와서 정리 

ㅎ ㅏ₩~~~~~~~~~

 

# justifyContent 

정의 : flex container의 main-axis을 따라 정렬을 정의하는 프로퍼티

기본값 : start

가능한 값 : start / end / center / spaceBetween / spaceAround / spaceEvenly

저는 대충 뭐 워드나 한글의 글자 정렬과 비슷하다고 생각했기에 direction을 row로 테스트 해봅시다. 

rootContainer.flex.height(100)
    .direction(.row)
    .backgroundColor(.systemYellow)
    .define { flex in
        flex.addItem().backgroundColor(UIColor.brown).size(50)
        flex.addItem().backgroundColor(UIColor.gray).size(50)
    }

아마도 가장 많이 쓰일 center로 테스트.

rootContainer.flex.height(100)
    .direction(.row)
    .justifyContent(.center) // ✅
    .backgroundColor(.systemYellow).define { flex in
        flex.addItem().backgroundColor(UIColor.brown).size(50)
        flex.addItem().backgroundColor(UIColor.gray).size(50)
    }

이러면 

요렇게 정렬됩니다. 

왜냐? 지금 direction이 row. 즉 main-axis가 x축이기에 x축을 따라서 item들이 정렬되기 때문입니다.

그래서 요렇게 x축을 따라서 이동하다 x축의 center에 정렬되게 되는 것이죠.

주의할 점은.... 

이렇게 container에 추가된 flex item들이 x축-y축 center로 정렬되지 않는다는 것!!!!!!!!!!!!!!!!!! 

당연하죠?!:;

 

 

# alignItems

정의 : flex container의 현재 main-axis의 cross-axis를 따라 정렬되는 방식을 정의하는 프로퍼티

기본값 : stretch

가능한 값 : stretch / start / end / center / baseline

 

alignItems는 방금 봤던 justifyContent와 유사한데요.

justifyContent가 flex container의 main-axis을 따라 정렬을 정의하는 프로퍼티였다면,

alignItemsmain-axis의 cross-axis를 따라 정렬되는 방식을 정의하는 프로퍼티입니다.

같은 예를 사용해보면,

rootContainer.flex.height(100)
    .direction(.row)
    .backgroundColor(.systemYellow)
    .define { flex in
        flex.addItem().backgroundColor(UIColor.brown).size(50)
        flex.addItem().backgroundColor(UIColor.gray).size(50)
    }

현재 direction은 row. main-axis는 x니까.. cross-axis는 y입니다. 

그럼 만약에 alignItems에 end를 줬다고 생각해봅시다.

justifyContent 같았으면 현재 main-axis를 따라가므로, end를 줬다면 현재 axis인 x를 따라갔을테니  

이렇게 됐겠죠.

하지만!!!!! alignItems은 cross-axis를 따라가게 되고,

end를 줬으니.. column axis의 끝에 위치하게 됩니다.

이렇게 말이죠.

가장 직관적으로 이해할 수 있는 것 같이 end 같이 보여서 선택했는데, justifyContent과의 차이점이 눈에 잘 들어오시나요? 

그럼 아주아주 간단한 문제!

1. direction이 row. 즉 main-axis가 row인 상태에서 alignItems(.center)를 하면 어떻게 될까

정답:

2. direction이 column. 즉 main-axis가 y인 상태에서 alignItems(.center)를 하면 어떻게 될까

정답:

justifyContent와 똑같이..주의할 점은....

이렇게 container에 추가된 flex item들이 x축-y축 center로 정렬되지 않는다는 것!!!!!!!!!!!!!!!!!!!

 

🐥 : ㅋ그럼 저렇게 딱 x축-y축에 대해 center주고 싶으면 어떻게해냐되냐거

✔️ justifyContent: flex container의 main-axis에 따라 정렬을 정의하는 프로퍼티

✔️ alignItems: flex container의 현재 main-axis의 cross-axis를 따라 배치되는 방식을 정의하는 프로퍼티

하나는 main-axis..하나는 corss-axis...

둘 다 center를 먹이면..? 

rootContainer.flex.height(150)
    .justifyContent(.center) // ✅ 
    .alignItems(.center) // ✅
    .backgroundColor(.systemYellow).define { flex in
        flex.addItem().backgroundColor(UIColor.brown).size(50)
        flex.addItem().backgroundColor(UIColor.gray).size(50)
    }

이렇게 x축-y축 center에 위치하도록 할 수 있습니다.

아마도 가장 많이 쓰지 않을까..

 

# alignSelf

정의 : 부모(parent)의 alignItems를 재정의(override)하여 자식(child)이 cross direction으로 정렬되는 방식을 제어하는 프로퍼티

기본값 : auto (flex container의 alignItems을 사용함을 의미) 

가능한 값 : auto / stretch / start / end / center / baseline

아묻따 예제 코드부터 봅시다.

rootContainer.flex.height(150)
    .direction(.row)
    .justifyContent(.center)
    .alignItems(.center) // ✅
    .backgroundColor(.systemYellow).define { flex in
        flex.addItem()
        .alignSelf(.end) // ✅
        .direction(.row)
        .backgroundColor(.systemRed)
        .define { flex in
            flex.addItem().backgroundColor(UIColor.brown).size(50)
            flex.addItem().backgroundColor(UIColor.gray).size(50)

        }
    }

코드가 길어보이지만..;;; alignItems와 alignSelf를 봐주세요.

자.. 우리가 

rootContainer.flex.height(150)
    .direction(.row)
    .justifyContent(.center)
    .alignItems(.center) // ✅
    ....

딱 여기까지만 보면, 위에서 봤던거랑 똑같이

요렇게 나오겠죠??

근데 제가 또 다른 container를 만들고, 그 container에 alignSelf를 .end를 줬습니다. 

그리고 또 다른 container안에 갈색 View, 회색 View를 넣어줬어요. 

rootContainer.flex.height(150)
    .direction(.row)
    .justifyContent(.center)
    .alignItems(.center) // ✅
    .backgroundColor(.systemYellow).define { flex in
        flex.addItem()
        .alignSelf(.end) // ✅
        .direction(.row)
        .backgroundColor(.systemRed)
        .define { flex in
            flex.addItem().backgroundColor(UIColor.brown).size(50)
            flex.addItem().backgroundColor(UIColor.gray).size(50)

        }
    }

자!!! 그럼 alignSelf가 부모(parent)의 alignItems를 재정의(override)하기 때문에 

.alignItems(.center)
 ㄴ alignSelf(.end)


이렇게 되어있으면 alignItems은 .end가 먹여지게 됩니다. 

그럼 어떻게 되냐..alignItems랑 똑같습니다. alignSelf도 역시 cross-axis를 따라서 정렬되므로

지금 alignSelf가 먹은 container의 main-axis가 x이기 때문에 (direction(.row))

x의 cross-axis인 y를 따라 정렬됩니다. 

그러니까... 

요렇게 나오게 됩니다. (justifyContent는 center로 되어있으니까 center인거임) 

 

alignSelf는 flex container에 안줘도되고, item에 줘도 됩니다. 

rootContainer.flex.height(150)
    .direction(.row)
    .justifyContent(.center)
    .alignItems(.center)
    .backgroundColor(.systemYellow).define { flex in
        flex.addItem().backgroundColor(UIColor.brown).size(50)
        	.alignSelf(.end) // ✅
        flex.addItem().backgroundColor(UIColor.gray).size(50)
    }

이렇게 갈색 View에 alignSelf end를 주면, 

요렇게 갈색 View만 바뀌게 됩니다.

 

 

# alignContent

⚠️ 주의 : alignContent를 이해하려면 wrap에 대한 이해가 필요합니다. ⚠️

정의 : FlexLayout에 있는 정의가 너무 이해가 안가서 다른 블로그에 있는 정의를 가져왔습니다. 

- flex-wrap 속성의 값이 wrap인 경우, 아이템들의 가로폭의 합이 콘테이너의 가로폭을 넘어가면 아이템이 다음 줄로 내려갑니다.
이때 여러 줄이 되어버린 아이템들의 정렬을 어떻게 할지 정하는 속성이 align-content입니다

- 기본값은 stretch로, 높이를 꽉 채웁니다.

기본값 : stretch

가능한 값 : stretch / start / end / center / baseline

자..가장 처음의 예제 코드로 돌아가서 alignContent를 줘봅시다.

rootContainer.flex.height(100)
    .direction(.row)
    .alignContent(.center) // ✅
    .backgroundColor(.systemYellow).define { flex in
        flex.addItem().backgroundColor(UIColor.brown).size(50)
        flex.addItem().backgroundColor(UIColor.gray).size(50)
    }

🐥 : direction이 row고... alignContent를 center로 줬으니까.. 

이렇게 나오겠구만...

결과 : 

 🐥 : ⁉️

기본적으로 flex의 wrap값은 unwrap인데요. unwrap이면 alignContent는 아무 효과가 없습니다.

wrap일 때 alignContent가 효과가 있는거 ㅇㅇ

flex-wrap 속성의 값이 wrap인 경우, 아이템들의 가로폭의 합이 콘테이너의 가로폭을 넘어가면 아이템이 다음 줄로 내려갑니다. 
이때 여러 줄이 되어버린 아이템들의 정렬을 어떻게 할지 정하는 속성이 align-content입니다


일단 줄이 넘어가도록 여러개의 view를 넣어봅시다.

rootContainer.flex.height(150)
    .direction(.row)
    .wrap(.wrap) // ✅
    .backgroundColor(.systemYellow).define { flex in
        for _ in 1...10 {
            flex.addItem().backgroundColor(colors.randomElement()!).size(50)
        }
    }

wrap으로 설정되어있기 때문에 다음 줄로 잘 내려왔는데요.

이 상태에서 alignContent를 적용해봅시다. 대충 center로..

rootContainer.flex.height(150)
    .direction(.row)
    .wrap(.wrap)
    .alignContent(.center) // ✅
    .backgroundColor(.systemYellow).define { flex in
        for _ in 1...10 {
            flex.addItem().backgroundColor(colors.randomElement()!).size(50)
        }
    }

대충 잘 적용된 것을 볼 수 있읍니다..

 

다시한번 말하지만, alignContent는 wrap이 적용되어있어야하므로..

wrap이 적용되지 않은 상태에서는 alignContent를 해도

그냥 이렇게 나오니 주의 ㅎ

column도 동일하니까 

공식문서에 있는 이미지 참고하면 될 것 같아요!

 


 

아 드디어 알겠내 편-안

혹시!! 틀린 부분이 있다면 꼭 댓글 부탁드립니다~ 🙏

 

 

[참고]

https://www.codingfactory.net/12377

https://github.com/layoutBox/FlexLayout

반응형