Angular 6/7 CSS媒体查询不适用于孙子

时间:2018-11-06 07:03:42

标签: html css media-queries angular6 angular7

在使用以下组件的体系结构的应用程序上应用媒体查询(响应行为)时遇到一些问题

  • 基本组件::它使用默认封装,在某些情况下,在某些情况下,我们在应用PrimeNG外部模块时会使用外部插件。想法是将这些基本组件移至其他应用程序。这些都集成在其自己的共享模块中。

  • 品牌组件::它重用基本组件,应用自定义样式和翻译文本,做一些特定的事情,并且使用本机封装(以与基本组件区分开),但是它没有应用业务逻辑。这些都集成在其自己的品牌模块中,该模块导入共享模块。

  • 业务组件::它重用品牌组件并在此处应用自己的业务逻辑(在多个视图中使用时)。这些都集成在其自己的导入品牌模块的业务模块中。这些组件实现默认的角度封装模式。

然后我们拥有视图,这些视图集成在其自己的模块中并导入业务模块。它将使用品牌和/或业务组件,在这里我们面临一些与CSS媒体查询有关的问题。这些视图使用默认的角度封装模式。

具体情况是,我们试图针对特定视图自定义输入字段,以便针对响应情况正确运行(移动设备,平板电脑和台式机的方向不同)。为此,我们使用外部插件的角度弹性布局(测试版7)

此输入字段位于基础组件上,但我们将其作为商标用例。我们想要的是更改其在商标上设置的默认宽度/高度,以适应将其封装的div容器。

这是我们到目前为止所做的:

特定视图的scss:

// MEDIA QUERIES
:host ::ng-deep {

  @media screen and (min-width: 300px) and (orientation: portrait)  {
    .inputField,
    .inputFieldEditing,
    .inputFieldChanged,
    .inputFieldDisabled {
      width: 95%;
    }
  }

  @media screen and (min-width: 300px) and (orientation: landscape)  {
    .inputField,
    .inputFieldEditing,
    .inputFieldChanged,
    .inputFieldDisabled {
      width:(80px * 2.625);
    }
  }

  @media screen and (min-width: 480px) and (orientation: landscape)  {
    .inputField,
    .inputFieldEditing,
    .inputFieldChanged,
    .inputFieldDisabled {
      width:(80px * 2.9);
    }
  }

  @media screen and (min-width: 640px) and (orientation: portrait)  {
    .inputField,
    .inputFieldEditing,
    .inputFieldChanged,
    .inputFieldDisabled {
      width:(80px * 2);
      height:(16px * 1.6);
    }
  }

  @media screen and (min-width: 640px) and (orientation: landscape)  {
    .inputField,
    .inputFieldEditing,
    .inputFieldChanged,
    .inputFieldDisabled {
      width:(80px * 2.68);
      height:(16px * 1.6);
    }
  }

  @media screen and (min-width: 768px) and (orientation: portrait) {
    .inputField,
    .inputFieldEditing,
    .inputFieldChanged,
    .inputFieldDisabled {
      width:(80px * 3.3);
      height:(16px * 1.6);
    }
  }

  @media screen and (min-width: 768px) and (orientation: landscape) {
    .inputField,
    .inputFieldEditing,
    .inputFieldChanged,
    .inputFieldDisabled {
      width:(80px * 3.5);
      height:(16px * 1.6);
    }
  }

  @media screen and (min-width: 900px) and (orientation: portrait) {
    .inputField,
    .inputFieldEditing,
    .inputFieldChanged,
    .inputFieldDisabled {
      width:(80px * 3.5);
      height:(16px * 1.625);
    }
  }

  @media screen and (min-width: 900px) and (orientation: landscape) {
    .inputField,
    .inputFieldEditing,
    .inputFieldChanged,
    .inputFieldDisabled {
      width:(80px * 1.875);
      height:(16px * 1.625);
    }
  }

  @media screen and (min-width: 1200px) and (orientation: portrait) {
    .inputField,
    .inputFieldEditing,
    .inputFieldChanged,
    .inputFieldDisabled {
      width:(80px * 3.75);
      height:(16px * 1.625);
    }
  }

  @media screen and (min-width: 1200px) and (orientation: landscape) {
    .inputField,
    .inputFieldEditing,
    .inputFieldChanged,
    .inputFieldDisabled {
      width:(80px * 2.5);
      height:(16px * 1.625);
    }
  }
}

存在以前的自定义类,并在品牌输入字段组件中使用了这些自定义类,以便根据不同的情况更改其UX。

品牌输入字段组件模板文件:

<sh-input-field [id]="id"
                [caption]="caption | translate"
                [(model)]="userInput"
                [placeholder]="placeholder | translate"
                [type]="inputType"
                [color]="color"
                [font-size]="fontsize"
                [isDisabled]="!enabled"
                [style]="{'width': width,
                          'height': height}"
                [status]="status"
                [baseClass]="INPUT_CLASS_ENABLED"
                [extendedClass]="extendedClass"
                [stateClasses]="{
                                  focusedOn: INPUT_CLASS_EDITING,
                                  enabledOn: INPUT_CLASS_ENABLED,
                                  enabledOff: INPUT_CLASS_DISABLED,
                                  valueChanged: INPUT_CLASS_CHANGED
                                }"
              [passwordWeakCaption]="passwordWeakCaption"
              [passwordMediumCaption]="passwordMediumCaption"
              [passwordStrongCaption]="passwordStrongCaption"
              [isPasswordFeedbackShown]="isPasswordFeedbackShown">
</sh-input-field>

品牌输入字段组件scss文件:

/* CAPTION */
.uiElemSideCaptionLeft,
.uiElemSideCaptionRight,
.uiElemSideCaptionDisabled {
  position: relative;
  display: inline-block;
  padding-top: 2px;
  text-align: left;
  font-size: 14px;
  -ms-opacity: 1;
  opacity: 1;
  color: #333;
}

.uiElemSideCaptionRight {
  -ms-opacity: 1;
  opacity: 1;
  text-align: right;
}

.uiElemSideCaptionDisabled {
  -ms-opacity: 0.4;
  opacity: 0.4;
}

/* INPUT-FIELD */
.inputField,
.inputFieldEditing,
.inputFieldChanged,
.inputFieldDisabled {
  position: relative;
  display: inline-block;
  height: 16px;
  width: 80px;
  padding: 4px;
  background-color: #dddddd;
  border-width: 1px;
  border-color: #979797;
  border-style: solid;
  font-size: 14px;
  text-align: left;
  color: rgba(0, 0, 0, 1);
  -ms-opacity: 1;
  opacity: 1;
}

.inputFieldEditing {
  -ms-opacity: 1;
  opacity: 1;
  background-color: #eee;
  height: 14px;
  border-width: 2px;
  border-color: #F8E71C;
  color: rgba(0, 0, 0, 1);
  border-style: solid;
}

.inputFieldChanged {
  -ms-opacity: 1;
  opacity: 1;
  background-color: rgba(245, 166, 35, 0.5);
  height: 16px;
  border-width: 1px;
  border-color: #979797;
  color: rgba(0, 0, 0, 1);
  border-style: solid;
}

.inputFieldDisabled {
  -ms-opacity: 0.6;
  opacity: 0.6;
  height: 16px;
  background-color: lightgray;
  border-width: 1px;
  border-color: #979797;
  border-style: solid;
  color: rgba(0, 0, 0, 1);
}

品牌输入字段组件定义:

@Component({
  selector: 'br-input-field',
  templateUrl: './input-field.component.html',
  styleUrls: ['./input-field.component.scss'],
  encapsulation: ViewEncapsulation.Native
})

基本输入字段组件模板文件:

<div class="sh-input-field-global-container">
  <div class="sh-input-field-label-container" *ngIf="caption !== '' && caption !== undefined && caption !== null">
    <label [for]="id">{{caption}}</label>
  </div>
  <div class="sh-input-field-container" [ngClass]="extendedClass">
    <input *ngIf="controlType !== 'password'"
           [ngClass]="getCssClases('sh-input-field', baseClass)"
           [attr.id]="id"
           [placeholder]="placeholder"
           [disabled]="isDisabled"
           (focus)="InvokeFocus($event)"
           (blur)="InvokeBlur($event)"
           (keyup.enter)="InvokeKeyUpEnterEvent($event)"
           (keyup.escape)="InvokeKeyUpEscapeEvent($event)"
           [(ngModel)]="model"
           [attr.name]="formName"
           [maxLength]="length"
           [type]="controlType"
           [ngStyle]="style"/>
    <input *ngIf="controlType === 'password'"
            [ngClass]="GetCssClases('sh-input-field', baseClass)"
            [attr.id]="id"
            [disabled]="isDisabled"
            (focus)="InvokeFocus($event)"
            (blur)="InvokeBlur($event)"
            (keyup.enter)="InvokeKeyUpEnterEvent($event)"
            (keyup.escape)="InvokeKeyUpEscapeEvent($event)"
            [(ngModel)]="model"
            [attr.name]="formName"
            [maxLength]="length"
            [type]="controlType"
            pPassword
            [promptLabel]="placeholder"
            [weakLabel]="passwordWeakCaption"
            [mediumLabel]="passwordMediumCaption"
            [strongLabel]="passwordStrongCaption"
            [feedback]="isPasswordFeedbackShown"
            [ngStyle]="style"/>
  </div>
</div>

基本输入字段组件定义:

@Component({
  selector: 'sh-input-field',
  templateUrl: './input-field.component.html',
  styleUrls: ['./input-field.component.scss']
})

那么这里可能出什么问题了? 我们是否在特定视图上错误地使用了:host:ng-deep??我们已经看到,如果我们直接在品牌输入字段sass文件上应用这些媒体查询,效果很好(删除:host:ng-deep标签)

2 个答案:

答案 0 :(得分:1)

  

但是,我必须在媒体查询上设置的所有属性值中添加!important才能生效。

为解决此问题,我在Vikas上提到了in this link

您可以将其放在单独的文件中,并将其包含在将要使用的任何文件中。

$phone : '(max-width: 480px)';
$phone-landscape : '(max-height: 480px)';
$tablet-portrait: '(max-width: 767px)';
$tablet-landscape: '(min-width: 768px) and (max-width: 979px) and (max-height: 768px)';
$large-desktop: '(min-width: 1200px)';
$non-retina: 'screen and (-webkit-max-device-pixel-ratio: 1)';
$retina: '(min--moz-device-pixel-ratio: 1.5), 
                    (-o-min-device-pixel-ratio: 3/2), 
                    (-webkit-min-device-pixel-ratio: 1.5), 
                    (min-device-pixel-ratio: 1.5), 
                    (min-resolution: 144dpi), 
                    (min-resolution: 1.5dppx)';

@mixin respond-to($media) {
    @media only screen and #{$media} {
        @content;
    }
}

,然后在声明中使用调用:

.bookItem {
    max-height: 450px;
    min-height: 150px;
    padding: 25px;

    @include respond-to($phone) {
      max-height: 150px;
      padding: 15px;
    }
}

它有效。

答案 1 :(得分:0)

尝试使用empty()代替:host /deep/,如下所示

:host ::ng-deep

使用:host /deep/ { /*your style goes here*/ } 代替encapsulation: ViewEncapsulation.None