It's been a couple hours already that I am struggling with my CSS.
I'm trying to add a box-shadow on an element of my website that is composed of 3 divs : #top #content and #bot.
Here is a picture to help you visualize what I deal with :
Having the box-shadow on the left and right of the div #content was kind of the easy part, but I'm really struggling for the top and bottom part. I can't make anything that looks decently clean.
Here is my code :
body {
margin-top: 30px;
}
div#content {
padding: 20px 30px 20px 30px;
color: #515348;
font-size: 76%;
line-height: 1.6em;
height: 100px;
background: #FFF;
width: 240px;
margin-right: auto;
margin-left: auto;
border-left: 1px solid grey;
border-right: 1px solid grey;
box-shadow: 0 9px 0px 0px white, 0 -9px 0px 0px white, 8px 0 14px -4px rgba(33, 33, 33, 0.6), -8px 0 14px -4px rgba(33, 33, 33, 0.5);
}
#top {
background: #FFF;
height: 10px;
width: 300px;
margin: 0 auto;
position: relative;
-webkit-border-radius: 8px 8px 0px 0px;
-moz-border-radius: 8px 8px 0px 0px;
border-radius: 8px 8px 0px 0px;
behavior: url(/PIE.htc);
border-top: 1px solid grey;
border-left: 1px solid grey;
border-right: 1px solid grey;
box-shadow: 0 9px 0px 0px white, -8px 0 14px -4px rgba(33, 33, 33, 0.5), 8px 0 14px -4px rgba(33, 33, 33, 0.6), -8px 0 14px -4px rgba(33, 33, 33, 0.5);
}
#bot {
background: #FFF;
height: 10px;
width: 300px;
margin: 0 auto;
position: relative;
-webkit-border-radius: 0px 0px 8px 8px;
-moz-border-radius: 0px 0px 8px 8px;
border-radius: 0px 0px 8px 8px;
behavior: url(/PIE.htc);
border-bottom: 1px solid grey;
border-left: 1px solid grey;
border-right: 1px solid grey;
box-shadow: 8px 4px 14px 4px rgba(33, 33, 33, 0.5), 0 9px 0px 0px white, 8px 0 14px -4px rgba(33, 33, 33, 0.6), -8px 0 14px -4px rgba(33, 33, 33, 0.5);
}
<div id="top"></div>
<div id="content"></div>
<div id="bot"></div>
Any idea about making this thing a bit "cleaner" ?
Quick Edit: The box-shadow on the bot part actually didn't look that bad on my screen, i had found some better settings that I since lost by trying different configurations.
Shadow all around the shape:
The image provided in question (when seen along with the snippet) is a bit confusing on whether you are looking for a shadow on only the sides (or) for the entire shape as a whole.
If you are looking to add a shadow to the entire shape then one option is to add one pseudo-element to the container element such that it is equal to the height of the container + the top + the bottom element. This pseudo-element should also be given border-radius and be positioned above the container by the same no. of pixels as the height of the top element (inversed). Adding the required box-shadow to this pseudo-element will produce the expected output.
body {
margin-top: 30px;
}
div#content {
position: relative;
height: 100px;
width: 240px;
padding: 20px 30px 20px 30px;
margin-right: auto;
margin-left: auto;
color: #515348;
font-size: 76%;
line-height: 1.6em;
background: #FFF;
border-left: 1px solid grey;
border-right: 1px solid grey;
}
div#content:before {
position: absolute;
content: '';
left: 0px;
top: -10px; /* positioning above makes shadow extend above */
height: calc(100% + 20px); /* to offset for top and bottom */
width: 100%;
border-radius: 8px;
z-index: -1; /* to send the elements and their shadow behind */
box-shadow: 6px 0px 6px 0px rgba(33, 33, 33, 0.25), -6px 0px 6px 0px rgba(33, 33, 33, 0.25), 0px 6px 6px 0px rgba(33, 33, 33, 0.25), 0px -6px 6px 0px rgba(33, 33, 33, 0.25);
}
#top {
position: relative;
height: 10px;
width: 300px;
margin: 0 auto;
background: #0F0;
border-radius: 8px 8px 0px 0px;
border: 1px solid grey;
border-width: 1px 1px 0px 1px;
}
#bot {
position: relative;
height: 10px;
width: 300px;
margin: 0 auto;
background: #00F;
border-radius: 0px 0px 8px 8px;
border: 1px solid grey;
border-width: 0px 1px 1px 1px;
}
<div id="top"></div>
<div id="content"></div>
<div id="bot"></div>
Shadow all around shape but fades towards top and bottom:
In this approach the shadow is applied all around the shape but it gradually fades towards the top and bottom. These are all the possible variants based on description, image in question and snippet. You can choose the one which suits you best.
body {
margin-top: 30px;
}
div#content {
position: relative;
height: 100px;
width: 240px;
padding: 20px 30px 20px 30px;
margin-right: auto;
margin-left: auto;
color: #515348;
font-size: 76%;
line-height: 1.6em;
background: #FFF;
border-left: 1px solid grey;
border-right: 1px solid grey;
}
div#content:before {
position: absolute;
content: '';
left: 0px;
top: -8px; /* positioning above makes shadow extend above */
height: calc(100% + 16px); /* to offset for top and bottom */
width: 100%;
border-radius: 8px;
z-index: -1; /* to send the elements and their shadow behind */
box-shadow: 6px 0px 6px 0px rgba(33, 33, 33, 0.25), -6px 0px 6px 0px rgba(33, 33, 33, 0.25), 0px 0px 6px 0px rgba(33, 33, 33, 0.25), 0px 0px 6px 0px rgba(33, 33, 33, 0.25);
}
#top {
position: relative;
height: 10px;
width: 300px;
margin: 0 auto;
background: #0F0;
border-radius: 8px 8px 0px 0px;
border: 1px solid grey;
border-width: 1px 1px 0px 1px;
}
#bot {
position: relative;
height: 10px;
width: 300px;
margin: 0 auto;
background: #00F;
border-radius: 0px 0px 8px 8px;
border: 1px solid grey;
border-width: 0px 1px 1px 1px;
}
<div id="top"></div>
<div id="content"></div>
<div id="bot"></div>
Shadow only on sides:
Looking closely at the original image provided in the question, one thing that I can see is that you don't actually need a box-shadow on the top and bottom elements. You just need shadow on the container which extends a little above and below it. This can be achieved in a very hacky way by using just the container element alone but that's just way too complex and ugly.
So, the alternate option is to add one pseudo-element to the container element and position it a little bit above the container. Once box-shadow is added to this pseudo-element, the expected appearance will be achieved.
Note: In the below snippet, I've added a red colored shadow and also colored the top and bottom div just to illustrate how the shadow extend above and below the #content. I've also removed extra properties which are no longer required and shortened a few others.
I would also strongly recommend converting the three div into one as it would make the entire thing a lot more simpler.
body {
margin-top: 30px;
}
div#content {
position: relative;
height: 100px;
width: 240px;
padding: 20px 30px 20px 30px;
margin-right: auto;
margin-left: auto;
color: #515348;
font-size: 76%;
line-height: 1.6em;
background: #FFF;
border-left: 1px solid grey;
border-right: 1px solid grey;
}
div#content:before {
position: absolute;
content: '';
left: -1px;
top: -7px; /* positioning above makes shadow extend above */
height: calc(100% + 14px); /* to cover top and bottom */
width: 100%;
z-index: -1; /* to send the elements and their shadow behind */
box-shadow: 6px 0px 12px -6px rgba(255, 0, 0, 0.75), -6px 0px 12px -6px rgba(255, 0, 0, 0.75);
}
#top {
position: relative;
height: 10px;
width: 300px;
margin: 0 auto;
background: #0F0;
border-radius: 8px 8px 0px 0px;
border: 1px solid grey;
border-width: 1px 1px 0px 1px;
}
#bot {
position: relative;
height: 10px;
width: 300px;
margin: 0 auto;
background: #00F;
border-radius: 0px 0px 8px 8px;
border: 1px solid grey;
border-width: 0px 1px 1px 1px;
}
<div id="top"></div>
<div id="content"></div>
<div id="bot"></div>
Whats the point of having three divs instead of one?
box {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
width: 300px;
height: 120px;
background: #FFF;
border: 1px solid grey:
}
and then apply box shadow on selector as you wanted
Related
I have a div with the style as so:
.oval {
width: 100%;
height: 30%;
border-radius: 250px;
font-weight: bold;
line-height: 2em;
font-size: 1em;
color: #fff;
text-align: center;
}
And also a background color.
I want to add a shadow to this circle.
Is that possible?
I'm seeing conflicting information, with people saying that's inside the image, so you can't apply any styles to it, and other people suggesting that a style like that exists or there is a way to do it.
You can use the box-shadow property:
.oval {
width: 100%;
height: 30%;
border-radius: 250px;
font-weight: bold;
line-height: 2em;
font-size: 1em;
text-align: center;
box-shadow:0 0 2px 2px #999;
}
<div class="oval">text</div>
I think you are looking for box shadow:
-webkit-box-shadow: 0px 0px 30px 0px rgba(0, 0, 255, 0.67);
-moz-box-shadow: 0px 0px 30px 0px rgba(0, 0, 255, 0.67);
box-shadow: 0px 0px 30px 0px rgba(0, 0, 255, 0.67);
This link explains it: http://www.w3schools.com/cssref/css3_pr_box-shadow.aspAnd this link lets you experiment with it: http://www.cssmatic.com/box-shadow
Use box-shadow property:
.oval {
width: 150px;
height: 150px;
border-radius: 150px;
font-weight: bold;
font-size: 1em;
color: #fff;
text-align: center;
display: block;
background-color: red;
box-shadow: 3px 3px 3px #aaa;
}
<div class="oval"></div>
Box Shadow!
https://developer.mozilla.org/en-US/docs/Web/CSS/box-shadow
.circle {
width: 150px;
height: 150px;
background-color: yellow;
border-radius: 50%;
box-shadow: 5px 5px 5px #BC7046;
position: absolute;
top: 10px;
left: 10px;
}
.circle2{
box-shadow: -6px -6px 6px #BCAE46;
}
#square {
border-radius: 5px;
width: 170px;
height: 170px;
background-color: #D0DA72;
position: relative;
}
<div id=square>
<div class=circle></div>
<div class='circle circle2'></div>
</div>
I have a square div with rounded corners. Inside this div, I need to make this shape:
I want to do it with pure css, but there are two problems:
Little 1px green artifacts I can't get rid off (you can see them on the bottom and right sides)
I need a 1px red border around #login_form to also appear on top of my oval shapes.
Maybe there is a better way to cut the ovals.
Here is a jsfiddle of the below:
#login_form {
margin-left: auto;
margin-right: auto;
position: relative;
width: 200px;
height: 200px;
background: red;
border: 1px solid black;
border-radius: 10px;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
}
#white_ovale {
position: absolute;
right: -10px;
bottom: -10px;
width: 125px;
height: 80px;
background: white;
-webkit-border-radius: 225px 0px 7px 0px / 150px 0px 7px 0px;
-moz-border-radius: 225px 0px 7px 0px / 150px 0px 7px 0px;
border-radius: 225px 0px 7px 0px / 150px 0px 7px 0px;
}
#green_ovale {
position: absolute;
right: -21px;
bottom: -21px;
width: 139px;
height: 75px;
border: 0px;
background: #72B038;
-webkit-border-radius: 225px 20px 7px 0px / 130px 0px 7px 0px;
-moz-border-radius: 225px 20px 7px 0px / 130px 0px 7px 0px;
border-radius: 225px 20px 7px 0px / 130px 0px 7px 0px;
-webkit-box-shadow: inset -10px -10px 0px 10px white;
-moz-box-shadow: inset -10px -10px 0px 10px white;
box-shadow: inset -10px -10px 0px 10px white;
}
<div id="login_form">
<div id="white_ovale"></div>
<div id="green_ovale"></div>
</div>
you need overflow: hidden
you need a 3rd inner div which adds the border (Just think of an independent border that stacks i top of the others)
BTW: Don't id everthing. Use classes. Use id only if you need to. And try not the nest ids.
As a rule of thumb I use only class for CSS and idfor JS only
http://jsfiddle.net/Lt4x3ufg/1/
.login_form {
margin-left:auto;
margin-right:auto;
position: relative;
width: 200px;
height: 200px;
background: red;
border:1px solid red;
border-radius: 10px;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
overflow: hidden;
}
.login_form .border {
position: absolute;
top: -1px;
right: -1px;
bottom: -1px;
left: -1px;
border: 1px solid red;
border-radius: 10px;
}
.login_form .white_ovale {
position: absolute;
right: -10px;
bottom: -10px;
width: 125px;
height: 80px;
background: white;
-webkit-border-radius:
225px 0px 7px 0px / 150px 0px 7px 0px;
-moz-border-radius:
225px 0px 7px 0px / 150px 0px 7px 0px;
border-radius:
225px 0px 7px 0px / 150px 0px 7px 0px;
}
.login_form .green_ovale {
position: absolute;
right: -21px;
bottom: -21px;
width: 139px;
height: 75px;
border: 0px;
background: #72B038;
-webkit-border-radius: 225px 20px 7px 0px / 130px 0px 7px 0px;
-moz-border-radius: 225px 20px 7px 0px / 130px 0px 7px 0px;
border-radius: 225px 20px 7px 0px / 130px 0px 7px 0px;
-webkit-box-shadow: inset -10px -10px 0px 10px white;
-moz-box-shadow: inset -10px -10px 0px 10px white;
box-shadow: inset -10px -10px 0px 10px white;
}
<div class="login_form">
<div class="white_ovale"></div>
<div class="green_ovale"></div>
<div class="border"></div>
</div>
Single element solution
There is no need for extra markup. We can create:
the two shapes inside the div with ::before and ::after
the red border with the containing div itself
The excess background is cut off with overflow: hidden
Nice Advantage: Because IE 8 does not support the border-radius property, and will render an ugly square, we can use the double colon (::) for the pseudo elements. IE 8 does not recognise this syntax and will render just the red box. This is the modern syntax and valid CSS.
Note: For child elements to overlap the green shape, they should be given position: relative and z-index: 1
Browser Compatibility: Due to the border-radius property, IE 9 +. It is unlikely that you need the browser prefixes for the border-radius property.
Complete Example
I have condensed the CSS as much as possible.
.login_form {
margin: auto;
position: relative;
width: 200px;
height: 200px;
background: red;
border-radius: 10px;
overflow: hidden;
border: 1px solid red;
}
.login_form::before,
.login_form::after {
content: '';
display: block;
position: absolute;
right: -10px;
bottom: -10px;
width: 125px;
height: 80px;
background: white;
border-radius: 225px 0px 7px 0px / 150px 0px 7px 0px;
}
.login_form::after {
right: -31px;
bottom: -21px;
width: 149px;
height: 75px;
background: #72B038;
border-radius: 225px 20px 7px 0px / 130px 0px 7px 0px;
}
<div class="login_form"></div>
I have seen other complex effects being done with just CSS like the stacked paper effect:
http://jsfiddle.net/thefrontender/LwW7g/
<div class="slide expandable-slide">Title</div>
<div class="slide">Title</div>
.slide {
float: left;
display: block;
position: relative;
background: #FFF;
height: 10em;
width: 10em;
padding: 1em;
border: solid 2px #000;
margin-right: 2em;
}
.expandable-slide {
margin: 2em 2em 0 2em;
box-shadow: -1em -1em #666,
-2em -2em #333;
}
My need is very similar except the 2 outer edges need to connect with the main frontal div:
Anyone know of any tricks that can make this possible?
If you're able to use CSS pseudo-elements:
.slide {
position: relative;
width: 200px; /* arbitrary, adjust to taste */
height: 500px; /* arbitrary, adjust to taste */
border: 2px solid #000;
border-right-width: 40px; /* this is the 'depth' of the 'sides' */
border-bottom-width: 40px;
}
.slide::before {
content: '';
position: absolute;
top: -2px; /* to cover the top of the border */
left: 100%;
border: 20px solid #fff;
border-bottom-color: transparent; /* allows the containing element's border to be seen */
border-left-color: transparent;
}
.slide::after {
content: '';
position: absolute;
top: 100%;
left: -2px;
border: 20px solid #fff;
border-top-color: transparent;
border-right-color: transparent;
}
JS Fiddle demo.
The above uses the following HTML:
<div class="slide">Title</div>
You could stack multiple box shadows to attain the effect you're after:
.slide {
height: 200px;
width: 100px;
padding: 1em;
border: solid 2px #000;
}
.expandable-slide {
margin: 10px 10px 0 10px;
box-shadow: 1px 1px #999,
2px 2px #999,
3px 3px #999,
4px 4px #999,
5px 5px #999,
6px 6px #999,
7px 7px #999,
8px 8px #999,
9px 9px #999,
10px 10px #999;
}
jsFiddle example
You could do it this way (not the most elegant but works like a charm):
.expandable-slide {
margin: 2em 2em 0 2em;
box-shadow: 0.05em 0.05em #555,
0.1em 0.1em #555,
0.15em 0.15em #555,
0.2em 0.2em #555,
0.25em 0.25em #555,
0.3em 0.3em #555,
0.35em 0.35em #555,
0.4em 0.4em #555,
0.45em 0.45em #555,
0.5em 0.5em #555
;
}
fiddle
.expandable-slide {
position: relative;
margin: 2em 2em 0 2em;
box-shadow: 20px 25px 0px 0px #333;
}
.expandable-slide:before {
position: absolute;
content: "";
color: #333;
background: #333;
width: 0px;
height: 0px;
border-right: 15px solid #333;
border-top: 10px solid #333;
border-bottom: 15px solid #fff; /*match background color*/
border-left: 10px solid #fff;/*match background color*/
top: 194px;
left: 0px;
}
.expandable-slide:after {
position: absolute;
content: "";
color: #333;
background: #333;
width: 0px;
height: 0px;
border-bottom: 15px solid #333;
border-left: 10px solid #333;
border-right: 10px solid #fff; /*match background color*/
border-top: 15px solid #fff;/*match background color*/
top: 0px;
left: 194px;
}
I have two overlapping divs that have css3 box shadows. The trouble is that even when I set the z-index I will still need to eliminate one of the div's box-shadow. I have seen cases where negative spreads and zero values are used but I don't think that would work here.
The code I have now is:
#bulb-top {
position: relative;
width: 280px;
height: 280px;
background-color: #E5F7A3;
-webkit-border-radius: 280px;
-moz-border-radius: 280px;
border-radius: 280px;
border: 8px solid #FFF40C;
top: -430px;
margin-left: auto;
margin-right: auto;
-webkit-box-shadow: 0px 0px 15px 1px #FFF40C;
-moz-box-shadow: 0px 0px 15px 1px #FFF40C;
box-shadow: 0px 0px 15px 1px #FFF40C;
z-index: 4;
}
#bulb-bottom {
position: relative;
width: 140px;
height: 120px;
background-color: #E5F7A3;
-moz-border-radius-topleft: 0px;
-moz-border-radius-topright: 0px;
-moz-border-radius-bottomright: 30px;
-moz-border-radius-bottomleft: 30px;
-webkit-border-radius: 0px 0px 30px 30px;
border-radius: 0px 0px 30px 30px;
border-left: 8px solid #FFF40C;
border-right: 8px solid #FFF40C;
border-bottom: 8px solid #FFF40C;
top: -455px;
margin-left: auto;
margin-right: auto;
-webkit-box-shadow: 0px 0px 15px 1px #FFF40C;
-moz-box-shadow: 0px 0px 15px 1px #FFF40C;
box-shadow: 0px 0px 15px 1px #FFF40C;
z-index: 5;
}
http://jsfiddle.net/minitech/g42vq/3/
You can use the ::before pseudo-element to block out one side of the box shadow. It's not perfect, but it might be enough for your situation. Here's the updated jsFiddle.
#bulb-bottom:before {
background-color: #E5F7A3;
content: '';
display: block;
height: 30px;
margin: 0 auto;
position: relative;
top: -10px;
width: 140px;
}
I asked a question of creating a speech bubble in CSS and change the layout of the bubble based on the size of the screen in this thread. I got some hint by using the flexbox to determine the bubble arrow direction and layout. I used the CSS class to change the arrow orientation as shown in the thread. And int the following script, I use the natural item order to automatically layout the bubble. I assume the main tag only contains an image tag and a div (for speech bubble).
If the image tag is in front of div, we layout the image logo on the left and followed by a speech bubble on the right with an arrow pointing to the left.
If the image tag is behind the div, we layout the image logo on the right and with a speech bubble inserted in front of it with an arrow pointing to the right.
But in the case when the screen size is less than 600px, to avoid a slim speech bubble, I will rearrange the image and bubble vertically and with image shown on the top always. Here is the code
.speech {
display: flex;
flex-wrap: wrap;
align-items: flex-start;
flex-direction: row;
}
.speech img:first-child{
order: 0;
margin: 10px;
border: 3px solid #00CCFF;
box-shadow: 3px 3px 8px 0px rgba(0,0,0,0.3);
max-width: 25vw;
margin-right: 30px;
}
.speech img:last-child{
order: 0;
margin: 10px;
border: 3px solid #00FF99;
box-shadow: 3px 3px 8px 0px rgba(0,0,0,0.3);
max-width: 25vw;
margin-left: 30px;
}
.sp {
background: #efefef;
-webkit-border-radius: 4px;
border-radius: 4px;
font-size: 1.2rem;
line-height: 1.3;
max-width: 95%;
padding: 15px;
position: relative;
left:0px;
top: 20px;
filter: drop-shadow(6px 4px 0px rgba(0, 0, 0, 0.2));
border: 1px solid black;
}
div.sp:last-child::after {
border-left: 11px solid transparent;
border-right: 11px solid #efefef;
border-top: 11px solid #efefef;
border-bottom: 11px solid transparent;
content: "";
position: absolute;
left: -20px;
top: 8px;
filter: drop-shadow(-2px -1px 0px black);
order: 0;
}
div.sp:first-child::after {
content: "";
position: absolute;
border-left: 11px solid #efefef;
border-right: 11px solid transparent;
border-top: 11px solid #efefef;
border-bottom: 11px solid transparent;
right: -20px;
top: 8px;
filter: drop-shadow(2px -1px 0px black);
order: 0;
}
#media only screen and (max-width: 600px) {
.speech {
display: flex;
flex-wrap: nonwrap;
flex-direction: column;
background: #00cc00;
}
.speech img:first-child{
margin: 10px;
border: 3px solid green;
box-shadow: 3px 3px 8px 0px rgba(0,0,0,0.3);
max-width: 25vw;
margin-right: 30px;
order: -1;
}
div.sp:last-child::after {
content: '';
position: absolute;
top:-19px;
left: 11px;
width: 0;
height: 0;
border-left: 20px solid transparent;
border-right: 0px solid transparent;
border-top: 0px solid transparent;
border-bottom: 20px solid #efefef;
filter: drop-shadow(1px -2px 0px black);
order: 0;
}
.speech:nth-of-type(2n) {
align-items: flex-end;
}
div.sp:first-child::after {
content: '';
position: absolute;
top:-29px;
left: 84%;;
width: 0;
height: 0;
border-left: 20px solid transparent;
border-right: 0px solid transparent;
border-top: 0px solid transparent;
border-bottom: 20px solid red;
filter: drop-shadow(1px -2px 0px black);
order: 0;
}
.speech img:last-child{
margin: 10px;
border: 3px solid blue;
box-shadow: 3px 3px 8px 0px rgba(0,0,0,0.3);
max-width: 25vw;
margin-right: 0px;
right: 0px;
order: -1;
}
}
<main class="speech">
<img src="https://www.quackit.com/pix/samples/6m.jpg" alt="Sample photo">
<div class="sp">this is my example 1 <div>additional line</div></div>
</main>
</br></br></br>
<main class="speech">
<div class="sp">this is my example 2 <div>additionl line</div></div>
<img src="https://www.quackit.com/pix/samples/6m.jpg" alt="Sample photo">
</main>
Assuming all items on the flexbox container is of order ZERO. I use the natural order to determine the orientation of the bubble arrow, there you will see first-child and last-child to do the work. But when the screen size shrunk, I add order: -1; to move the image as the first item. But with that, I encounter two issues
1) I assume the second example should have the image aligned to the right and with a bubble below it. However, no matter how I align it, they always align to the left. (This issue is partially fixed after applying Brett's comment .speech:nth-of-type(2n) { align-items: flex-end; }, but the items in the case of flex-direction: row; still won't align all the way to the right)
2) In the second example, I assume the bubble should have the arrow moved to the top-right corner but it is still on the right side. And this issue seems to be caused by the order (I can tell it does not use the code within the #media after I change the order). (This issue is fixed about removing the html comment)
Please run the code, make it full screen and shrink the screen size to see the effect.
.speech {
display: flex;
flex-wrap: wrap;
align-items: flex-start;
flex-direction: row;
}
.speech img:first-child{
order: 0;
margin: 10px;
border: 3px solid #00CCFF;
box-shadow: 3px 3px 8px 0px rgba(0,0,0,0.3);
max-width: 25vw;
margin-right: 30px;
}
.speech img:last-child{
order: 0;
margin: 10px;
border: 3px solid #00FF99;
box-shadow: 3px 3px 8px 0px rgba(0,0,0,0.3);
max-width: 25vw;
margin-left: 30px;
}
.sp {
background: #efefef;
-webkit-border-radius: 4px;
border-radius: 4px;
font-size: 1.2rem;
line-height: 1.3;
max-width: 95%;
padding: 15px;
position: relative;
left:0px;
top: 20px;
filter: drop-shadow(6px 4px 0px rgba(0, 0, 0, 0.2));
border: 1px solid black;
}
div.sp:last-child::after {
border-left: 11px solid transparent;
border-right: 11px solid #efefef;
border-top: 11px solid #efefef;
border-bottom: 11px solid transparent;
content: "";
position: absolute;
left: -20px;
top: 8px;
filter: drop-shadow(-2px -1px 0px black);
order: 0;
}
div.sp:first-child::after {
content: "";
position: absolute;
border-left: 11px solid #efefef;
border-right: 11px solid transparent;
border-top: 11px solid #efefef;
border-bottom: 11px solid transparent;
right: -20px;
top: 8px;
filter: drop-shadow(2px -1px 0px black);
order: 0;
}
#media only screen and (max-width: 600px) {
.speech {
display: flex;
flex-wrap: nonwrap;
flex-direction: column;
background: #00cc00;
}
.speech:nth-of-type(2n) {
align-items: flex-end;
}
<!-- LOGO SPEECH -->
.speech img:first-child{
margin: 10px;
border: 3px solid green;
box-shadow: 3px 3px 8px 0px rgba(0,0,0,0.3);
max-width: 25vw;
margin-right: 30px;
order: -1;
}
div.sp:last-child::after {
content: '';
position: absolute;
top:-19px;
left: 11px;
width: 0;
height: 0;
border-left: 20px solid transparent;
border-right: 0px solid transparent;
border-top: 0px solid transparent;
border-bottom: 20px solid #efefef;
filter: drop-shadow(1px -2px 0px black);
order: 0;
}
<!-- SPEECH LOGO -->
div.sp:first-child::after {
content: '';
position: absolute;
top:-29px;
left: 84%;;
width: 0;
height: 0;
border-left: 20px solid transparent;
border-right: 0px solid transparent;
border-top: 0px solid transparent;
border-bottom: 20px solid red;
filter: drop-shadow(1px -2px 0px black);
order: 0;
}
.speech img:last-child{
margin: 10px;
border: 3px solid blue;
box-shadow: 3px 3px 8px 0px rgba(0,0,0,0.3);
max-width: 25vw;
margin-right: 0px;
right: 0px;
order: -1;
}
}
<main class="speech">
<img src="https://www.quackit.com/pix/samples/6m.jpg" alt="Sample photo">
<div class="sp">this is my example 1 <div>additional line</div></div>
</main>
</br></br></br>
<main class="speech">
<div class="sp">this is my example 2 <div>additionl line</div></div>
<img src="https://www.quackit.com/pix/samples/6m.jpg" alt="Sample photo">
</main>
I added .speech:nth-of-type(2n) { align-items: flex-end; } to your media query.
This will make every even numbered speech element move to the end. When you change the flex direction to column, align and justify flip roles. You might need to tweak some styles, but I believe this answers your question.