Prevent truncating of the box-shadow by "overflow: hidden" without paddings - html

Why I don't accept the padding solution of CSS overflow: hidden cuts shadow question is the paddings are the geometry and the box-shadow is the decoration; the decoration must not force the changing of geometry.
The conflict situation example
Suppose we have two themes for button component: with shadows and without shadows. To adapt the second theme with paddings, we need:
To interfere the geometry settings
To know the size of shadows.
And also: what if we place the element with different shadows in one container? We need to know the each shadow size?
About Z-Index solution
Generally, it does not work. There are the unknown for me conditions when it works so if you suggest this solution I ask you to clarify the conditions when it works.
The example which you can use is solution
The .Modal-MainSection element has overflow-y: scroll; settings for the cases when modal content is too large. Because of this, the shadow of buttons has been truncated:
<div class="Layout">
<div class="Modal">
<div class="Modal-TitleSection">
<div class="Modal-DummyTitle"></div>
</div>
<div class="Modal-MainSection">
<div class="Modal-DummyContent"></div>
<div class="Modal-ButtonsBar">
<button class="Button">Cancel</button>
<button class="Button">OK</button>
</div>
</div>
</div>
</div>
html {
height: 100%;
}
body {
height: 100%;
}
.Layout {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
background: #B2EBF2;
}
.Modal {
display: flex;
flex-direction: column;
width: 220px;
border-radius: 4px;
padding: 12px 14px;
overflow: hidden;
background: #42A5F5;
}
.Modal-TitleSection {
flex: 0 0 auto;
}
.Modal-DummyTitle {
width: 100px;
height: 20px;
background: #1976D2;
}
.Modal-MainSection {
flex: 1 1 auto;
overflow-x: hidden;
overflow-y: auto;
margin-top: 12px;
}
.Modal-DummyContent {
height: 140px;
background: #1976D2;
}
.Button {
border: none;
padding: 6px 8px;
box-shadow: 0 0 4px 4px #FFA726;
}
.Button + .Button {
margin-left: 12px;
}
.Modal-ButtonsBar {
margin-top: 12px;
display: flex;
justify-content: flex-end;
}
🌎 Fiddle
Also, assume that the buttons bar is the custom content. It means be does not know at advance when developing the modal component will be the buttons bar or no and which buttons will be.

Related

How to handle wrong width calculation when sizing text-overflow div?

I am creating a splitter-resizer in Angular to adjust the width of 2 panels. There are 2 horizontal sections and the columns widths on each side needs to be the same. However, I noticed that the width calculation is wrong at the boundary that touches the text overflow element. This causes the top and bottom panels to be off by roughly the size of a single text character.
What can I do to ensure the div width respects the ngStyle setting?
EDIT: I noticed that if I set width to undefined for the blue panel2, it seems the 2 panels size and align correctly, but I think that is not the correct way.
app.component.html
<div #container class="container">
<div class="section flex-container-row">
<div [ngStyle]="stylePanel1" class="panel1">1</div>
<div class="resizer" (click)="startdrag()" (mousedown)="startdrag($event)"></div>
<div [ngStyle]="stylePanel2" class="panel2 flex-container-row">2</div>
</div>
<div class="section flex-container-row">
<div [ngStyle]="stylePanel1" class="panel1">
<div class="longtext">this is a very long text that should be cut off when resizing.</div>
</div>
<div class="resizer" (click)="startdrag()" (mousedown)="startdrag($event)"></div>
<div [ngStyle]="stylePanel2" class="panel2">4</div>
</div>
</div>
app.component.scss
* {
box-sizing: border-box;
margin: 0; padding: 0;
}
html, body {
width: 100%;
height: 100%;
}
.container {
width: 100%;
height: 100%;
background-color: pink;
}
.section {
width: 100%;
height: 130px;
border: 1px solid magenta;
}
.flex-container-row {
display: flex;
flex-direction: row;
}
.resizer {
flex: 0 0 5px;
background-color: #ddd;
cursor: ew-resize;
}
.panel1 {
background-color: red;
width: 100px;
}
.panel2 {
background-color: blue;
}
.longtext {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
Instead of this.refContainer.nativeElement.clientWidth.
Can you please consider refContainer.nativeElement.getBoundingClientRect()

How to horizontally align items using flexbox?

Beginner here. For some reason in the website I'm coding, the to-be buttons don't align horizontally on the nav bar. I'm using flexbox, but even then it doesn't align them like how I want it to. There doesn't seem to be any problems in the code, either.
.topPart {
position: fixed;
overflow: hidden;
top: 0;
margin: 0px 15px 30px 15px;
width: 1790
padding: 30px;
border: 2px solid #3cc851;
background-color: #1f1f1f;
}
.topButtons {
display: flex;
flex-flow: row wrap;
justify-content: space-around;
align-items: flex-center;
height: 15px;
width: auto;
padding: 15px;
background-color: #fff;
color: #1f1f1f;
}
.topButtons .rightButtons {
text-align: right;
margin: auto 2px auto 1500px;
}
.topButtons .leftButtons {
text-align: left;
margin: auto 2% auto 2%;
}
<div class="topPart">
<h2> Website name I don't want to share </h2> <p> Website slogan I don't want to share </p>
<!-- later, make it so that the boxes of text are lined up like how it looks in the code using css -->
<div class="topButtons">
<div class="leftButtons">
<a href="index.html" class="home">home<a>
<a href="" class="mssg">mssg board<a>
<a href="database.html" class="data">database<a>
<a href="roleplay.html" class="rp">rp<a>
</div>
<div class="rightButtons">
dms
<a class="out">logout</a>
<a class="acc">acc</a>
</div>
</div>
</div>
The right buttons appear to be ~5px lower than the left ones. I'm at a complete loss here, there doesn't seem to be any errors in my code to cause this. Flexbox tags that should fix it don't do anything either, such as flex-direction: row; and justify-content.
What it looks like.
the div is a block element, so maintaining a width of auto would be essentially 100% of the available space which pushed the second div downwards.
try inline-flex or making the width a set amount rather than auto
This is happening due to the CSS properties of "text-align" and "margin" on ".leftButtons" and ".rightButtons" classes. You don't need to use these properties as you are using "display:flex" on ".topButtons" class. Horizontal and vertical alignment of child classes will manage by "justify-content: space-between;" and "align-items: center;" ".topButtons".
I have removed CSS properties of ".leftButtons" and ".rightButtons" classes. Updated "justify-content: space-between;" on ".topButtons" so that child classes horizontal align by leaving equal spaces between element.
I have also made some corrections in your markup which I have found, mentioned below:
(1) Anchor (/a) closure tags was missing of child ".leftButtons".
(2) In ".topPart" ";" was missing after width property declaration. Also added "px" of width value "1790".
Please check added code.
.topPart {
position: fixed;
overflow: hidden;
top: 0;
margin: 0px 15px 30px 15px;
width: 1790px;
padding: 30px;
border: 2px solid #3cc851;
background-color: #1f1f1f;
}
.topButtons {
display: flex;
flex-flow: row wrap;
/* justify-content: space-around; [old code] */
justify-content: space-between;
align-items: center;
height: 15px;
width: auto;
padding: 15px;
background-color: #fff;
color: #1f1f1f;
}
/*---- [old code]----*/
.topButtons .rightButtons {
/*text-align: right;
margin: auto 2px auto 1500px;*/
}
.topButtons .leftButtons {
/*text-align: left;
margin: auto 2% auto 2%;*/
}
<div class="topPart">
<h2> The Blood Tundra Kingdom </h2>
<p> - never talk about the blood tundra kingdom </p>
<!-- later, make it so that the boxes of text are lined up like how it looks in the code using css -->
<div class="topButtons">
<div class="leftButtons">
home
mssg board
database
rp
</div>
<div class="rightButtons">
dms
<a class="out">logout</a>
<a class="acc">acc</a>
</div>
</div>
</div>
You can define display: flex;,justify-content: space-between, align-items: center; in topPart class and equally divided width of inside div by this flex: 1 1 auto; css property. I hope below snippet will help you lot.
*,*:before,*:after{box-sizing: border-box;}
body{margin: 0; padding: 0}
.topPart {
position: fixed;
overflow: hidden;
top: 0;
padding: 30px 20px;
border-bottom: 2px solid #3cc851;
background-color: #fff;
width: 100%;
z-index: 100;
display: flex;
flex-flow: row wrap;
justify-content: space-between;
align-items: center;
}
.leftButtons {
flex: 1 1 auto;
text-align: left;
}
.centerButtons {
text-align: center;
flex: 1 1 auto;
}
.rightButtons {
text-align: right;
flex: 1 1 auto;
}
.centerButtons a, .rightButtons a{
display: inline-flex;
background-color: #ccc;
padding: 4px 5px;
text-decoration: none;
color: #444;
text-transform: capitalize;
}
<div class="topPart">
<div class="leftButtons">
<div>Website Name<br>Website slogan</div>
</div>
<div class="centerButtons">
home
mssg board
database
rp
</div>
<div class="rightButtons">
dms
<a class="out">logout</a>
<a class="acc">acc</a>
</div>
</div>

Show text on hovering a div under a flex-container

I have to create an icon navigation bar with webfont-icons on the top of the page, that is tiled 3 Sections:
upper-left: Icons are aligning on the left side
middle-center: Icons are aligning in the middle of the site
upper right: Icons are aligning on the right side
This part i got to work. With the following HTML ...
<div id="topNavigation">
<div id="topNavigationLeft">
<div class="iconButton makeAnIcon" data-icon="πŸ™ˆ"><span class="tooltiptext">The funky monkey</span></div>
<div class="iconButton makeAnIcon" data-icon="😎"><span class="tooltiptext">The cool smiley</span></div>
</div>
<div id="topNavigationMiddle">
<div class="iconButton makeAnIcon" data-icon="🚹"><span class="tooltiptext">Man rest room</span></div>
<div class="iconButton makeAnIcon" data-icon="🚺"><span class="tooltiptext">Woman rest room</span></div>
<div class="iconButton makeAnIcon" data-icon="🚾"><span class="tooltiptext">Water Closet</span></div>
</div>
<div id="topNavigationRight">
<div class="iconButton makeAnIcon" data-icon="🚻"><span class="tooltiptext">Mixed up rest room</span></div>
<div class="iconButton makeAnIcon" data-icon="🚼"><span class="tooltiptext">Baby room</span></div>
<div class="iconButton makeAnIcon" data-icon="🚽"><span class="tooltiptext">Toilet</span></div>
</div>
</div>
This is the CSS i had used:
.iconButton {
float: left;
margin-left: 10px;
margin-right: 10px;
}
.iconButton:hover {
color: #ff0000;
}
.iconButton .tooltiptext {
visibility: hidden;
width: 120px;
background-color: black;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 5px 0;
/* Position the tooltip */
position: absolute;
z-index: 1;
}
.iconButton:hover .tooltiptext {
visibility: visible;
}
.makeAnIcon:before
{
font-family: 'Arial';
content: attr(data-icon);
font-size:60px;
}
#topNavigation {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
align-items: center;
position: absolute;
width: 100%;
height: 80px;
top: 0px;
left: 0px;
margin: 0px;
padding: 0px;
border-bottom: 1px solid;
}
#topNavigationLeft {
display: flex;
justify-content: flex-start;
flex-wrap: nowrap;
height: 100%;
/* Debug Color */
/* background-color: rgba(255, 0, 0, 0.2); */
}
#topNavigationMiddle {
display: flex;
justify-content: center;
flex-wrap: nowrap;
height: 100%;
/* Debug Color */
/* background-color: #711e82; */
}
#topNavigationRight {
display: flex;
justify-content: flex-end;
flex-wrap: nowrap;
height: 100%;
/* Debug Color */
/* background-color: rgba(255, 0, 0, 0.2); */
}
See my fiddle: https://jsfiddle.net/schludi/yrgaf6p9/
Now i have to show a text UNDER the Icons on hover.
My problem is, that it is under the flex-container i have used and it should not affect further elements that will be added under the "topnavigation"-div.
When i am on the upper right side, the Text should appear left-aligned to the icon, that no scroll bars will be generated because the span element is too big. How can i do this?
First off, for ToolTips i would highly recommend using a plugin. You'll run into issues where the tooltip goes off the screen (either x or y) and you can't detect that at all with CSS.
However, lets answer your question.
So if you've got a div that's appearing underneath another element, there's one nice css property that will solve this for you! I see you've already used it. What you can do is add z-index to your element that you want on top. The higher the index, the higher the element will be visually.
.iconButton .tooltiptext {
display:none;
visibility: hidden;
width: 120px;
background-color: black;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 5px 0;
/* Position the tooltip */
position: absolute;
z-index: 9999; /* This is extreme, don't always default to 9999 */
}
Just make sure the z-index of the element you want on top is higher than the other elements. If it's still not on top, then the chances are the parent is lower than the other element that you want on top, so on your flex-container make sure that the z-index is lower than the parent of .tooltiptext
For your specific case, the following would keep the last tooltip within the bounds of the page. It's not very dynamic, though.
#topNavigationRight .iconButton:last-of-type .tooltiptext {
right: 0;
}

How can I completely hide elements that overflow their container vertically?

I have a fixed width and height container that consists of arbitrary height elements that need to be stacked vertically. How can I hide any elements that do not fit? overflow: hidden could still show the part of an element that doesn’t overflow.
.container {
border: 1px solid #eee;
height: 200px;
overflow: hidden;
}
.box {
background-color: #ccc;
line-height: 54px;
margin: 20px;
text-align: center;
width: 60px;
}
.incorrect {
background-color: #fa9;
}
<div class="container">
<div class="box">show</div>
<div class="box">show</div>
<div class="box incorrect">hide</div>
</div>
Assuming that your child elements have the same width as the container, this can be achieved by leveraging the containing box created from the flex property.
The trick is to use flex-flow: column wrap; in conjunction with overflow: hidden; on the container. The former dictates that the content is stacked vertically and that anything that does not fit should be wrapped into a second column, outside of the content box of the container. The latter dictates that this second column (and any subsequent columns) should be hidden.
.container {
width: 300px;
height: 200px;
display: flex;
flex-flow: column wrap;
overflow: hidden;
}
.box {
width: 300px;
height: 75px;
}
.box:nth-child(1) {
background: red;
}
.box:nth-child(2) {
background: green;
}
.box:nth-child(3) {
background: blue;
}
<div class='container'>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
An easy way of doing this would be to use CSS columns instead of flex.
Just use a column-width equal to the width of the container. Apply break-inside: avoid on child divs. And there you go.
It resolves all of the asks:
[..]have a fixed width and height container that consists of arbitrary
height elements that need to be stacked vertically. How can I hide any
elements that do not fit?
You can notice that the red div (the last one) is hidden completely.
Example Snippet:
* { box-sizing: border-box; margin: 0; padding: 0; }
.container {
border: 1px solid #999;
height: 200px; width: 300px;
overflow: hidden;
column-width: 300px;
}
.box {
padding: 8px; text-align: center; color: #fff;
width: 250px; height: 80px;
break-inside: avoid
}
.box:nth-child(1) { background: #3b3; }
.box:nth-child(2) { background: #33b; width: 200px; height: 75px; }
.box:nth-child(3) { background: #b33; }
<div class="container">
<div class="box">show</div>
<div class="box">show</div>
<div class="box">hide</div>
</div>
Note: As of now, Firefox is still a problem area with CSS columns. The break-inside, although documented on MDN, is buggy in Firefox. The bug is still open: https://bugzilla.mozilla.org/show_bug.cgi?id=549114.

CSS3 flexbox: vertically center two different sized items, but make their top align at the same height

inspired by:
Flexbox - Vertically Center and Match Size
fiddle with the problem:
http://jsfiddle.net/Nbknc/22/
what i try to achieve:
I want to get the text of the second button to start at the same height as the text on the first button.
HTML
<section class="buttonsSection">
<a class="button" href="#">Very Long Word aaaa xx ccc ddd ee</a>
<a class="button" href="#">Short Phrase</a>
</section>
CSS
.button {
padding: 10px 15px;
width: 150px;
background-color: deepskyblue;
color: white;
margin: 3px;
text-align: top;
display: flex;
flex-direction: column;
justify-content: center;
}
.buttonsSection {
margin: 30px 0;
display: flex;
justify-content: center;
height: 500px;
}
body
{
width: 20%; /*Simulate page being reduced in size (i.e. on mobile)*/
margin: 0 auto;
}
a photo of how i want it to look
EDIT the reason I use flexbox and justify-content is to make it work with different screen sizes. Space is perfectly distributed with flexbox. Adding a padding is suboptimal as it will stay the same, even if the screen has a height of say 200px.
Here is one way, one where I added an extra wrapper that centers
.buttonsSection {
display: flex;
flex-direction:column;
justify-content: center;
height: 400px;
border: 1px solid;
width: 200px;
margin: 0 auto;
}
.buttonsWrap {
margin: 30px 0;
display: flex;
}
.button {
padding: 50px 15px;
width: 150px;
background-color: deepskyblue;
color: white;
margin: 3px;
text-align: top;
}
<section class="buttonsSection">
<div class="buttonsWrap">
<a class="button" href="#">Very Long Word aaaa xx ccc ddd ee</a>
<a class="button" href="#">Short Phrase</a>
</div>
</section>
You can accomplish this by removing the flexbox properties from the button and adding a span around your button text with the following CSS:
position: relative;
top: 50%;
transform: translateY(-50%);
You may need to play with those percentages to get things to line up ideally, but this gets you in the ballpark.
http://codepen.io/angeliquejw/pen/QNdrOZ?editors=0100
I updated the fiddle
Suggest if its not that you require.
http://jsfiddle.net/Nbknc/30/
.button {
padding: 50% 15px 0 15px;
width: 150px;
background-color: deepskyblue;
color: white;
margin: 3px;
}
.buttonsSection {
margin: 30px 0;
display: flex;
flex-direction:row;
height: 500px;
}
Now its much simpler , now you can add the required padding to your button
so that the text in both button will align with equal top padding .
UPDATE
included some changes to your html and css
http://jsfiddle.net/Nbknc/32/
Edit: http://jsfiddle.net/Dneilsen22/36yL3y5m/5/
Removing the justify-content for .button and increasing the top padding would accomplish this.
.button {
padding: 100px 15px;
width: 150px;
background-color: deepskyblue;
color: white;
margin: 3px;
text-align: top;
display: flex;
flex-direction: column;
}